Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions docs/manifest/json-ref/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ pagination_next: null
pagination_prev: null
---

The [C2PA specification](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_manifests) describes a manifest with a binary structure in JPEG universal metadata box format ([JUMBF](https://www.iso.org/standard/84635.html)) that includes JSON as well as binary data for things like encryption keys and thumbnail images. Because the binary structure is hard to understand and program to, the SDK defines a JSON manifest structure that's a declarative language for representing and creating a binary manifest.

The JSON manifest is an abstract translation layer that's easier to understand than the binary format. It can describe everything in the underlying binary format except for binary data such as thumbnails that are included by a structure called a _resource reference_. To generate a binary manifest, the SDK assembles all the JSON objects, resource references, and ingredients defined, and then converts them into different assertions and other objects as required.

These JSON references are generated from the JSON schemas for [ManifestDefinition](https://docs.rs/c2pa/latest/c2pa/struct.ManifestDefinition.html) and [Reader](https://docs.rs/c2pa/latest/c2pa/struct.Reader.html) objects (_structs_ in Rust terminology):

- [ManifestDefinition](manifest-def.mdx): Defines a manifest and builds a manifest store.
- [Reader](reader.mdx): Reads and validates a manifest.
Please see:
- [ManifestDefinition JSON reference](manifest-def.mdx)
- [Reader JSON reference](reader.mdx)
6 changes: 4 additions & 2 deletions docs/manifest/json-ref/manifest-def.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ hide_table_of_contents: true
import ManifestReference from './manifest-ref.js';

:::danger Warning
This is a beta release of this reference. It is a work in progress and may not be accurate or complete.
This is a beta release of this reference. It is a work in progress and may not be accurate or complete. It was generated from the unmodified JSON schema generated from c2pa-rs on 05/09/2025.
:::

This page is generated from the unmodified JSON schema generated from c2pa-rs on 05/09/2025.
The [C2PA specification](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_manifests) describes a manifest with a binary structure in JPEG universal metadata box format ([JUMBF](https://www.iso.org/standard/84635.html)) that includes JSON as well as binary data for things like encryption keys and thumbnail images. Because the binary structure is hard to understand and program to, the SDK defines a JSON manifest structure that's a declarative language for representing and creating a binary manifest.

The JSON manifest is an abstract translation layer that's easier to understand than the binary format. It can describe everything in the underlying binary format except for binary data such as thumbnails that are included by a structure called a _resource reference_. To generate a binary manifest, the SDK assembles all the JSON objects, resource references, and ingredients defined, and then converts them into different assertions and other objects as required.

<ManifestReference htmlPath="./manifest-def.html" />
6 changes: 4 additions & 2 deletions docs/manifest/json-ref/reader.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ hide_table_of_contents: true
import ManifestReference from './manifest-ref.js';

:::danger Warning
This is a beta release of this reference. It is a work in progress and may not be accurate or complete.
This is a beta release of this reference. It is a work in progress and may not be accurate or complete. It was generated from the unmodified JSON schema generated from c2pa-rs on 05/09/2025.
:::

This page is generated from the unmodified JSON schema generated from c2pa-rs on 05/09/2025.
The [C2PA specification](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_manifests) describes a manifest with a binary structure in JPEG universal metadata box format ([JUMBF](https://www.iso.org/standard/84635.html)) that includes JSON as well as binary data for things like encryption keys and thumbnail images. Because the binary structure is hard to understand and program to, the SDK defines a JSON manifest structure that's a declarative language for representing and creating a binary manifest.

The JSON manifest is an abstract translation layer that's easier to understand than the binary format. It can describe everything in the underlying binary format except for binary data such as thumbnails that are included by a structure called a _resource reference_. To generate a binary manifest, the SDK assembles all the JSON objects, resource references, and ingredients defined, and then converts them into different assertions and other objects as required.

<ManifestReference htmlPath="./reader.html" />
Original file line number Diff line number Diff line change
@@ -1,31 +1,48 @@
---
id: ingredients
title: Ingredients
id: reading-ingredients
title: Reading ingredients
---

## Overview
## Overview

Digital assets are often not created entirely from scratch, but instead created from one or more existing assets, for example placing an image into a layer in Photoshop. Such constituent assets are called _ingredients_.
Digital assets are often not created entirely from scratch, but instead created from one or more existing assets, for example placing an image into a layer in Photoshop. Such constituent assets are called _ingredients_.

This documentation covers C2PA v1 ingredients. The [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_ingredient) also describes improved v2 ingredients.
Existing manifests may contain any of these three kinds of ingredients:
- V1, with labels starting with `c2pa.ingredient` (deprecated). See [Reading legacy manifest data](legacy.md#legacy-ingredients).
- V2, with labels starting with `c2pa.ingredient.v2` (deprecated). See [Reading legacy manifest data](legacy.md#legacy-ingredients).
- V3, with labels starting with `c2pa.ingredient.v3`, which addresses the issue of validating ingredients after redaction.

:::note
The C2PA Technical Specification describes _ingredient assertions_ but the CAI SDK treats ingredients separately as their own objects in the JSON manifest rather than as a type of assertion.
:::

## Ingredient objects

Each ingredient used to create an asset is listed in the [JSON manifest](manifest/json-ref/manifest-def.mdx) `ingredients` array. When an ingredient itself has Content Credentials, those manifests are included in the composed asset's manifest store to keep the provenance data intact.
The `ingredients` array contains an element for each ingredient used to create an asset. When an ingredient itself has Content Credentials, those manifests are included in the composed asset's manifest store to keep the provenance data intact.

The `ingredients` array contains an [ingredient object](manifest/json-ref/manifest-def.mdx#ingredient) for each ingredient. The only required property of the `ingredient` object is the `title` property, which usually is the source file name.
The `ingredients` array contains an [ingredient object](manifest/json-ref/reader.mdx#ingredient) for each ingredient. The `ingredient` object's `title` property (usually is the source file name) is required for v1 and v2 ingredients, but optional for v3 ingredients.

### The label property

The `label` property is used in two ways:

- When creating an ingredient, you can assign any value you like to `label` and we will match that with the the action `ingredientIds` to find an associated action. The value you specify here does not end up in the manifest. it is optional and only used for doing action/ingredient pairing.
- When reading a manifest, the `label` will always exist and correspond to actual label assigned to the ingredient. It will be in the format you described below. Note that older v1 claims may have older forms of ingredient labels.

The `label` property for the first ingredient in a manifest is `c2pa.ingredient.v3` When there is more than one ingredient, subsequent labels have a monotonically increasing index: `c2pa.ingredient.v3__1`, `c2pa.ingredient.v3__2`, and so on.

### Other properties

Other important properties of the ingredient object include:
- `format`: MIME type of the source file.
- `document_id` and `instance_id` which are derived from the ingredient asset's XMP metadata.

- `format`: MIME type of the source file (optional).
- `document_id` (optional) and `instance_id` (required) which are derived from the ingredient asset's XMP metadata.
- `thumbnail`: Object with properties that identify the thumbnail image.
- `active_manifest`: For an ingredient with a manifest store, the label of the active manifest.
- `relationship`: One of `parentOf`, `componentOf`, or `inputTo`. See [Relationship](#relationship) below.

An ingredient assertion must always have a `relationship` and an `instance_id`, but the API will default `relationship` to `componentOf` if not specified and will generate an `instance_id` if you don't give it one. It will also always return a label.

For example:

```json
Expand All @@ -52,10 +69,12 @@ The ingredient object's `relationship` property describes its relationship to th
| Value of `relationship` | Description |
|--------------------------|-------------|
| `parentOf` | The current asset is a derived asset or asset rendition of this ingredient. This relationship value is also used with update manifests. There can be at most one parent ingredient in a manifest. |
| `componentOf` | This ingredient is one of the assets that composes the current asset. |
| `componentOf` | This ingredient is one of the assets that composes the current asset. This is the default value. |
| `inputTo` | This ingredient was used as input to a computational process, such as an AI/ML model, that led to the creation or modification of this asset. |

## Validation status
## Validation results

The [ValidationResults](/docs/manifest/json-ref/reader#validationresults) object contains the the validation results for the active manifest and any changes to ingredients.

When ingredients are added, the SDK validates their Content Credentials (if any). However, the validation status of an ingredient does not imply anything about the validation status of the composed asset containing the ingredient. In other words:
- A composed asset's Content Credentials may be valid, but one or more of its ingredients may have invalid Content Credentials. For example, test file [adobe-20220124-XCA.jpg](https://contentcredentials.org/verify?source=https://spec.c2pa.org/public-testfiles/image/jpeg/adobe-20220124-XCA.jpg)
Expand Down Expand Up @@ -109,6 +128,3 @@ As noted above, the test file [adobe-20220124-CIE-sig-CA.jpg](https://contentcre
The [C2PA public-testfiles](https://spec.c2pa.org/public-testfiles/image/) repository has several examples of images with multiple ingredients:
- [Image with two ingredients](https://contentcredentials.org/verify?source=https://spec.c2pa.org/public-testfiles/image/jpeg/adobe-20220124-CAICA.jpg); [View JSON manifest store](https://spec.c2pa.org/public-testfiles/image/jpeg/manifests/adobe-20220124-CAICA/manifest_store.json)
- [Image with seven ingredients](https://contentcredentials.org/verify?source=https://spec.c2pa.org/public-testfiles/image/jpeg/adobe-20220124-CAIAIIICAICIICAIICICA.jpg); [View JSON manifest store](https://spec.c2pa.org/public-testfiles/image/jpeg/manifests/adobe-20220124-CAIAIIICAICIICAIICICA/manifest_store.json)



159 changes: 159 additions & 0 deletions docs/manifest/reading/legacy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
---
id: legacy-manifests
title: Reading legacy manifest data
---

As much as possible, an application should **write** manifest data that conforms to the recent [version 2.2](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html) C2PA technical specification, but should be able to **read and validate** manifest data that conforms to earlier versions of the specification. This ensures that your application is "backward-compatible" and can still validate older assets with claims that were written in the past.

## Legacy ingredients

Old manifests may contain these kinds of deprecated ingredient data:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While these labels will show up so they can detect them, the API will return the same ingredient option for any of them. But the field contents may vary depending on the version.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"...the API will return the same ingredient option ..."

I think this should be "...same ingredient OBJECT..." right?


- V1 ingredients, with labels that begin with `c2pa.ingredient`.
- V2 ingredients, with labels that begin with `c2pa.ingredient.v2`.

While these labels will show up so you can detect them, the API will return the same ingredient object for all of them, but the field contents may vary depending on the version.


## Legacy actions

Existing manifests may contain two versions of actions: original v1 actions, with label `c2pa.actions`, and revised v2 actions, with label `c2pa.actions.v2`. While a v1 action is fully specified in its actions array, a v2 action may either be fully specified in an element of the actions array or it may be derived from an element in the templates array with the same action name.

As with Ingredients, a single `Actions` object handles both versions of actions. The label will be different for each version, and you may want to to check for both labels or use `starts_with`.

<!--
FROM GAVIN:
The rules for parsing actions templates needs to be added somewhere along with how to handle localizations.

I think we need to provide an action resolver for this.
-->

## Legacy metadata assertions

Existing manifests may contain individual assertions for each metadata standard:

- [Exif assertion](#exif-assertion)
- [IPTC metadata assertion](#iptc-metadata-assertion)
- [Creative Work assertion](#creative-work-assertion)

In the latest version of the SDK, Exif and IPTC assertions are now CAWG assertions, and the CreativeWork assertion is not supported at all.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreativeWork should not be used but there are some new alternatives via CAWG such as the AssetRef assertion and Cawg Identity claims aggregator for social media.


### Exif assertion

Exchangeable image file (Exif) format is a standard for storing technical metadata in image files of JPEG, TIFF, PNG, and other formats. Most digital cameras (including smartphones), scanners and other digital capture devices use Exif to store information such as device make and model, shutter speed, ISO number, date and time of capture, location, and so on. For more information on Exif, see the [Exif specification](https://www.cipa.jp/std/documents/download_e.html?DC-008-Translation-2019-E).

Use an Exif assertion to add Exif information to the asset in a way that can be validated cryptographically. An Exif assertion has the label `stds.exif`.

Here is a simple example:

```json
"assertions": [
...
{
"label": "stds.exif",
"data": {
"@context" : {
"exif": "http://ns.adobe.com/exif/1.0/"
},
"exif:GPSVersionID": "2.2.0.0",
"exif:GPSLatitude": "39,21.102N",
"exif:GPSLongitude": "74,26.5737W",
"exif:GPSAltitudeRef": 0,
"exif:GPSAltitude": "100963/29890",
"exif:GPSTimeStamp": "2019-09-22T18:22:57Z"
}
}
...
]
```

### IPTC metadata assertion

An International Press Telecommunications Council (IPTC) metadata assertion represents properties from the [IPTC Photo Metadata Standard](https://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata) and [Video Metadata Standard](https://www.iptc.org/standards/video-metadata-hub/recommendation/) that describe ownership, rights, and descriptive metadata about an asset.

An IPTC assertion has the label `stds.iptc` and is stored in JSON-LD format using the XMP field names and structures specified in the IPTC standards.

Earlier versions of the C2PA specification defined the `stds.iptc.photo-metadata` label for IPTC photo metadata; starting with version 1.3, the C2PA specification defines the `stds.iptc` assertion that includes video metadata as well.

See also [IPTC Photo Metadata User Guide](https://www.iptc.org/std/photometadata/documentation/userguide/).

For example:

```json
...
"assertions": [
...
{
"label": "stds.iptc",
"data": {
"@context" : {
"Iptc4xmpCore": "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/",
"Iptc4xmpExt": "http://iptc.org/std/Iptc4xmpExt/2008-02-29/",
"dc" : "http://purl.org/dc/elements/1.1/",
"photoshop" : "http://ns.adobe.com/photoshop/1.0/",
"plus" : "http://ns.useplus.org/ldf/xmp/1.0/",
"xmp" : "http://ns.adobe.com/xap/1.0/",
"xmpDM" : "http://ns.adobe.com/xmp/1.0/DynamicMedia/",
"xmpRights" : "http://ns.adobe.com/xap/1.0/rights/"
},
"photoshop:DateCreated": "Aug 31, 2022",
"dc:creator": [ "Julie Smith" ],
"Iptc4xmpExt:DigitalSourceType": "https://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture",
"dc:rights": "Copyright (C) 2022 Example Photo Agency. All Rights Reserved.",
"photoshop:Credit": "Julie Smith/Example Photo Agency via Example Distributor",
"plus:licensor": [
{
"plus:LicensorName": "Example Photo Agency",
"plus:LicensorURL": "http://examplephotoagency.com/images/"
}
],
"xmpRights:WebStatement": "http://examplephotoagency.com/terms.html",
"xmpRights:UsageTerms": [
"Not for online publication. Germany OUT"
],
"Iptc4xmpExt:LocationCreated": {
"Iptc4xmpExt:City": "San Francisco"
},
"Iptc4xmpExt:PersonInImage": [
"Erika Fictional"
],
"Iptc4xmpCore:AltTextAccessibility": "Photo of Erika Fictional standing in front of the Golden Gate Bridge at sunset."
}
},
...
]
```

### Creative work assertion

The deprecated creative work metadata assertion has the label `stds.schema-org.CreativeWork`.

For example:

```json
...
"assertions": [
...
{
"label": "stds.schema-org.CreativeWork",
"data": {
"@context": "https://schema.org",
"@type": "CreativeWork",
"url": "https://stock.adobe.com/615559889"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This url can now be supplied via the AssetRef assertion.

},
"kind": "Json"
},
...
]
```

## Legacy training and data mining assertion

Old manifests may have training and data mining assertions with the following entry keys:

- `c2pa.data_mining`
- `c2pa.ai_training`
- `c2pa.ai_generative_training`
- `c2pa.ai_inference`

These assertions have been replaced by [CAWG training and data mining assertions](../writing/assertions-actions.md#cawg-training-and-data-mining-assertion) with `cawg.*` entry keys.
Loading