C2PA Assertion
Specification
The C2PA format embeds a TRACE assessment as a cryptographically signed assertion inside a media file. Unlike page-level or feed-level metadata, C2PA credentials travel with the file — surviving download, re-hosting, and platform migration. This is the durability-first format for long-lived or high-stakes content.
What is C2PA?
The Coalition for Content Provenance and Authenticity (C2PA) is an open technical standard for attaching verifiable provenance data to media files. It was developed by Adobe, Microsoft, BBC, Intel, Sony, and Truepic, and is now maintained by a working group under the Joint Development Foundation.
C2PA works by embedding a manifest into a file's binary data. The manifest contains assertions — structured data blocks that describe facts about the content. The manifest is signed with a cryptographic certificate so that any modification to the file after signing can be detected.
TRACE defines a custom assertion type — trace.assessment — that producers add to a C2PA manifest alongside standard assertions like AI generation disclosure (c2pa.ai.generative_training_and_inference), thumbnail, and exif data.
The trace.assessment Label
C2PA identifies assertion types by label string. The TRACE assertion label is:
Label naming follows C2PA conventions: a vendor-domain prefix (trace) followed by a period and a descriptive noun (assessment). The label is case-sensitive and must be used exactly as shown.
trace.assessment assertion type is submitted for registration with the C2PA Assertion Registry. Until registration is confirmed, it functions as a custom assertion with the full label as identifier. Custom assertions are fully supported by all C2PA-compliant tools.
Data Fields in trace.assessment
The data object of a trace.assessment assertion carries the TRACE assessment payload. Field names and semantics are identical to the JSON-LD specification; the structure is the same data model in a different container.
{
// Assertion identification
"specVersion": "1.0",
"@context": "https://tracestandard.org/schema/v1",
// Content identification
"contentTitle": "string, required",
"contentType": "podcast|article|video|image|audio|document|other",
// Producer and community
"producer": "string, required",
"communityRepresented": "string, required",
// AI disclosure
"aiGenerated": boolean,
"aiTools": ["string"],
"aiRole": "primary|partial|assisted|none",
// Assessment metadata
"assessmentDate": "YYYY-MM-DD, required",
"assessedBy": "self|third-party|name",
"nextReviewDate": "YYYY-MM-DD",
// Track and disqualification
"track": "A|B, required",
"disqualified": boolean, required,
"disqualifierTriggered": "DQ1|DQ2",
// Scores (omit when disqualified)
"scores": {
"transparency": { "score": int, "max": int },
"sourceIntegrity": { "score": int, "max": int },
"displacement": { "score": int, "max": int },
"consentAttribution": { "score": int, "max": int },
"benefitFlow": { "score": int, "max": int },
"accountability": { "score": int, "max": int },
"governanceDurability": { "score": int, "max": int }
// governanceDurability: Track B only
},
// Totals and verdict (omit when disqualified)
"totalScore": integer, required,
"maxScore": integer, required,
"verdict": "string, required — see verdict values",
// References
"cardURL": "URI to TRACE scorecard"
}
| Field | Status | Notes |
|---|---|---|
| specVersion | required | Always "1.0" for this version. Used by consumers to handle schema evolution. |
| @context | required | Must be "https://tracestandard.org/schema/v1". Links this assertion to the canonical schema. |
| contentTitle | required | Title of the content. May differ from the file name. |
| producer | required | Producer name as a string. In C2PA, producer identity is also typically captured in the manifest's claim_generator and ingredient fields; this field is the TRACE-specific version. |
| communityRepresented | required | Free-text description of the community the content is about or from. |
| assessmentDate | required | ISO 8601 date: YYYY-MM-DD. Should be close to the manifest signing date. |
| track | required | "A" or "B". |
| disqualified | required | true or false. When true, omit scores, totalScore, maxScore, and verdict. |
| totalScore, maxScore | required | Required when disqualified is false. |
| verdict | required | Required when disqualified is false. See Verdict Values. |
| scores, aiGenerated, aiTools, aiRole, assessedBy, nextReviewDate, disqualifierTriggered, cardURL | optional | Same semantics as JSON-LD spec. Include as many as are applicable. |
Complete C2PA Manifest with TRACE Assertion
This example shows how a trace.assessment assertion sits alongside standard C2PA assertions in a full manifest. The format shown is C2PA JUMBF (the binary format) represented as its JSON equivalent for readability.
{
"claim_generator": "Cariboo Signals Publishing Tool/1.0",
"format": "audio/mpeg",
"title": "Ep 12: Water Rights on the Chilcotin",
"assertions": [
// Standard C2PA AI generation disclosure
{
"label": "c2pa.ai.generative_training_and_inference",
"data": {
"dataTypes": [
{ "type": "trainedAlgorithmicData" }
]
}
},
// Standard C2PA creation info
{
"label": "c2pa.created",
"data": {
"dateTime": "2026-05-15T09:00:00-07:00",
"actors": [{ "name": "Cariboo Signals" }]
}
},
// ─── TRACE assertion ──────────────────────────────────
{
"label": "trace.assessment",
"data": {
"specVersion": "1.0",
"@context": "https://tracestandard.org/schema/v1",
"contentTitle": "Ep 12: Water Rights on the Chilcotin",
"contentType": "podcast",
"producer": "Cariboo Signals",
"communityRepresented": "Tsilhqot'in Nation; rural Cariboo, BC",
"aiGenerated": true,
"aiTools": ["Claude", "ElevenLabs"],
"aiRole": "partial",
"assessmentDate": "2026-05-15",
"assessedBy": "self",
"track": "A",
"disqualified": false,
"scores": {
"transparency": { "score": 3, "max": 4 },
"sourceIntegrity": { "score": 2, "max": 3 },
"displacement": { "score": 2, "max": 2 },
"consentAttribution": { "score": 3, "max": 4 },
"benefitFlow": { "score": 3, "max": 5 },
"accountability": { "score": 2, "max": 2 }
},
"totalScore": 15,
"maxScore": 20,
"verdict": "Sound",
"cardURL": "https://tracestandard.org/cards/cariboo-ep12"
}
}
// ─────────────────────────────────────────────────────
],
"signature": {
"alg": "Es256",
// ... certificate chain truncated for brevity
}
}
Where C2PA Can Be Embedded
C2PA manifests can be embedded in a growing list of file types. Support varies by tool. Confirmed types:
Adding a TRACE Assertion to a File
Several tools support adding C2PA manifests with custom assertions. The TRACE assertion's data object is valid JSON, so any tool that accepts custom assertion data can embed it.
customAssertions field.Using c2patool to add a TRACE assertion
{
"claim_generator": "MyPublishingTool/1.0",
"assertions": [
{
"label": "trace.assessment",
"data": {
"specVersion": "1.0",
"@context": "https://tracestandard.org/schema/v1",
"contentTitle": "Ep 12: Water Rights on the Chilcotin",
"producer": "Cariboo Signals",
"communityRepresented": "Tsilhqot'in Nation; rural Cariboo",
"track": "A",
"disqualified": false,
"totalScore": 15,
"maxScore": 20,
"verdict": "Sound",
"assessmentDate": "2026-05-15"
}
}
]
}
# Embed the TRACE assertion into an audio file
c2patool episode-12.mp3 \
--manifest trace-manifest.json \
--signer-path my-cert.pem \
--signer-alg Es256 \
--output episode-12-signed.mp3
Reading and Verifying TRACE Assertions
A TRACE assertion in a C2PA manifest can be read and cryptographically verified by any C2PA-compatible tool. Verification confirms both that the assertion data is intact and that the signing certificate is trusted.
| Tool | Type | What it verifies |
|---|---|---|
| c2patool verify | CLI | Full manifest verification including certificate chain, assertion integrity, and all assertion labels and data. Outputs JSON. |
| contentcredentials.org/verify | Web app | Upload a file to verify its manifest. Displays all assertions including custom types. No account required. |
| c2pa-js in browser | SDK | Verify and display C2PA assertions client-side. Use to build a TRACE badge reader directly into a web page. Query by assertion label "trace.assessment" to extract TRACE-specific data. |
# Read all assertions from a file c2patool episode-12-signed.mp3 --show-manifest # Output includes a block like: { "label": "trace.assessment", "data": { "verdict": "Sound", "totalScore": 15, ... } }
Using C2PA and JSON-LD Together
The C2PA assertion and the JSON-LD block are not alternatives — they are complementary. The data model is identical; only the container differs. A recommended pattern for podcast episodes:
| Layer | Format | Where | Purpose |
|---|---|---|---|
| Episode page | JSON-LD | HTML <head> |
Search indexing, human-readable verification, linking to scorecard |
| RSS feed | XML namespace | <item> element |
Podcast app display, feed aggregator indexing |
| Audio file | C2PA assertion | MP3 / M4A binary | Durable, tamper-evident, travels with the file |
Version History
| Version | Date | Status | Notes |
|---|---|---|---|
| 1.0 | May 2026 | Draft | Initial draft. Assertion label defined. Submission to C2PA Assertion Registry pending. |