---
title: Common Integration Patterns
url: https://docs.kaltura.com/docs/rich-media-cms-apis/content-management/custom-metadata-common-integration-patterns
---

## Common Integration Patterns


### Upsert Pattern

Check if metadata exists for an object, then add or update accordingly:


```bash
# Step 1: Check if metadata exists
curl -X POST "$KALTURA_SERVICE_URL/service/metadata_metadata/action/list" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "filter[objectType]=KalturaMetadataFilter" \
  -d "filter[objectIdEqual]=$KALTURA_ENTRY_ID" \
  -d "filter[objectTypeEqual]=1" \
  -d "filter[metadataProfileIdEqual]=$PROFILE_ID"

# Step 2a: If totalCount=0, add new metadata
curl -X POST "$KALTURA_SERVICE_URL/service/metadata_metadata/action/add" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "metadataProfileId=$PROFILE_ID" \
  -d "objectType=1" \
  -d "objectId=$KALTURA_ENTRY_ID" \
  --data-urlencode 'xmlData=<metadata><Department>Engineering</Department></metadata>'

# Step 2b: If totalCount>0, update existing (use ID from step 1)
curl -X POST "$KALTURA_SERVICE_URL/service/metadata_metadata/action/update" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "id=$METADATA_ID" \
  --data-urlencode 'xmlData=<metadata><Department>Marketing</Department></metadata>'
```


### Metadata-Driven Automation

Use a metadata field to trigger automated workflows via webhooks:

1. Define a metadata profile with a status field (e.g., `ProcessOCR` with values `Yes`/`No`)
2. Create an HTTP event notification template that fires on `metadata.OBJECT_DATA_CHANGED`
3. In the webhook handler, check the field value and trigger processing
4. Update the metadata field to track completion

See [Webhooks API](/docs/rich-media-cms-apis/integration/webhooks) for event notification configuration.

### Bulk Metadata Retrieval

Fetch metadata for multiple entries in one call using `objectIdIn`:


```bash
curl -X POST "$KALTURA_SERVICE_URL/service/metadata_metadata/action/list" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "filter[objectType]=KalturaMetadataFilter" \
  -d "filter[objectIdIn]=$ENTRY_ID_1,$ENTRY_ID_2,$ENTRY_ID_3" \
  -d "filter[objectTypeEqual]=1" \
  -d "filter[metadataProfileIdEqual]=$PROFILE_ID" \
  -d "pager[pageSize]=500"
```


### Bulk Upload with Metadata

When using Kaltura's bulk upload system, metadata is passed in `<customDataItems>` XML:


```xml
<customData metadataProfile="content_classification" metadataProfileId="12345">
  <xmlData>
    <metadata>
      <Department>Engineering</Department>
      <ProjectName>API Guides</ProjectName>
    </metadata>
  </xmlData>
</customData>
```


The `metadataProfile` attribute accepts the `systemName` (or the numeric ID). When updating via bulk XML, include ALL existing fields — the system replaces the entire XML document, so include every field value to preserve them.

### Schema Lookup by systemName

Use `systemNameEqual` filter for stable profile references in code:


```bash
curl -X POST "$KALTURA_SERVICE_URL/service/metadata_metadataProfile/action/list" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "filter[objectType]=KalturaMetadataProfileFilter" \
  -d "filter[systemNameEqual]=content_classification"
```


### Entry Cloning Behavior

When cloning an entry, metadata is conditionally copied. File-sync data is linked (not copied). In partner-copy scenarios, profile IDs are remapped if the profile was also copied.

### Cascade Delete

Deleting an entry, category, user, or partner cascades to delete all attached metadata instances. Deleting a metadata profile cascades to delete all metadata instances for that profile.
