Skip to content

C2PA Quick Start Guide

Get started with C2PA in 5 minutes! This guide will help you understand, verify, and create C2PA-signed content.

  1. Understanding C2PA
  2. Verifying C2PA Content
  3. Creating C2PA Content
  4. Next Steps

C2PA adds a cryptographically signed “manifest” to your media files containing:

  • Who: Creator/editor identity
  • What: Actions performed (created, edited, AI-generated)
  • When: Timestamps
  • How: Tools and settings used
  • From: Source materials (ingredients)
Original Photo → [Add C2PA Manifest] → Signed Photo
Contains metadata:
• Creator: John Doe
• Camera: Nikon Z9
• Date: 2025-11-21
• GPS: 37.7749°N, 122.4194°W
• Signature: ✓ Valid

When you edit:

Signed Photo → [Edit in Photoshop] → New Signed Photo
New manifest references
original as "ingredient"

Result: Complete provenance chain from original to current version.


No installation required!

  1. Visit https://contentcredentials.org/verify
  2. Drag and drop any image/video/document
  3. View provenance information:
    • Creator identity
    • Editing history
    • Signature status
    • Original content (if available)

Try it now with sample images from: https://contentauthenticity.org/examples

For automatic verification while browsing:

  1. Install Content Credentials Extension
    • Available for Chrome, Edge, Brave
  2. Browse normally
  3. Extension automatically detects C2PA content
  4. Click icon to view provenance details

For developers and power users:

Terminal window
# macOS/Linux (using Cargo)
cargo install c2patool
# macOS (using Homebrew)
brew install c2patool
# Windows
# Download from: https://github.com/contentauth/c2patool/releases
Terminal window
# Basic verification
c2patool photo.jpg
# Detailed JSON output
c2patool photo.jpg --detailed
# Save manifest to JSON file
c2patool photo.jpg --output manifest.json
# Check multiple files
c2patool *.jpg
File: photo.jpg
Status: ✓ Valid C2PA signature
Creator: John Doe (john@example.com)
Created: 2025-11-21T10:30:00Z
Camera: Nikon Z9
Signature: Valid
Certificate: DigiCert
Actions: Captured

Integrate verification into your app:

const c2pa = require('c2pa-node');
async function verify(imagePath) {
const manifest = await c2pa.read(imagePath);
if (manifest) {
console.log('Creator:', manifest.claim.creator);
console.log('Created:', manifest.claim.created);
console.log('Valid:', manifest.validation_status);
} else {
console.log('No C2PA data found');
}
}
verify('photo.jpg');
from c2pa import Reader
reader = Reader('photo.jpg')
manifest = reader.manifest()
if manifest:
print(f"Creator: {manifest.creator}")
print(f"Created: {manifest.created}")
print(f"Valid: {manifest.is_valid}")
else:
print("No C2PA data found")

No coding required:

  1. Open image in Photoshop/Lightroom
  2. Go to Edit → Content Credentials
  3. Fill in creator information
  4. Save file → C2PA manifest automatically added
  • Nikon Z9/Z8: Enable in camera settings → photos signed at capture
  • Leica M11-P/SL3: Automatic signing enabled
  • Sony Alpha series: Enable via firmware update

You need a signing certificate:

For Testing (Self-Signed):

Terminal window
# Generate test certificate (not trusted by validators)
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes

For Production:

  • Purchase certificate from trusted CA (DigiCert, GlobalSign, etc.)
  • Specify C2PA key usage requirements

Create manifest.json:

{
"claim_generator": "my-app/1.0",
"assertions": [
{
"label": "stds.schema-org.CreativeWork",
"data": {
"@context": "https://schema.org",
"@type": "CreativeWork",
"author": [
{
"@type": "Person",
"name": "John Doe"
}
]
}
},
{
"label": "c2pa.actions",
"data": {
"actions": [
{
"action": "c2pa.created"
}
]
}
}
]
}
Terminal window
# Sign with your certificate
c2patool photo.jpg \
--manifest manifest.json \
--signer-cert cert.pem \
--signer-key key.pem \
--output signed_photo.jpg
# Verify it worked
c2patool signed_photo.jpg
use c2pa::{Builder, SigningAlg};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut builder = Builder::from_file("input.jpg")?;
// Add creator assertion
builder.add_assertion("stds.schema-org.CreativeWork",
r#"{"author": [{"name": "John Doe"}]}"#)?;
// Sign and save
let signer = get_signer(); // Your certificate/key
builder.sign("output.jpg", signer)?;
Ok(())
}
const c2pa = require('c2pa-node');
async function sign(inputPath, outputPath) {
const manifest = {
claim_generator: 'my-app/1.0',
assertions: [
{
label: 'stds.schema-org.CreativeWork',
data: {
author: [{ name: 'John Doe' }]
}
}
]
};
const signer = {
cert: 'path/to/cert.pem',
key: 'path/to/key.pem'
};
await c2pa.sign(inputPath, outputPath, manifest, signer);
console.log('Signed successfully!');
}
sign('input.jpg', 'output.jpg');
from c2pa import Builder, Signer
# Create builder
builder = Builder.from_file('input.jpg')
# Add assertions
builder.add_assertion('stds.schema-org.CreativeWork', {
'author': [{'name': 'John Doe'}]
})
# Sign
signer = Signer('cert.pem', 'key.pem')
builder.sign('output.jpg', signer)
print('Signed successfully!')

Method 4: Editing Signed Content (Preserving Provenance)

Section titled “Method 4: Editing Signed Content (Preserving Provenance)”

When editing C2PA-signed content, reference the original as an “ingredient”:

Terminal window
# Edit and preserve chain
c2patool edited_photo.jpg \
--parent original_photo.jpg \
--manifest edit_manifest.json \
--signer-cert cert.pem \
--signer-key key.pem \
--output final_photo.jpg

The new manifest will reference original_photo.jpg as an ingredient, preserving the complete history.


Understand the Specification:

Explore Tools:

Common Questions:

Official Tutorials:

Code Examples:

Before Going Live:

  1. Get Production Certificate

    • Purchase from trusted CA (DigiCert, GlobalSign, etc.)
    • Ensure C2PA-compatible key usage
    • Cost: ~$50-500/year
  2. Secure Key Storage

    • Use Hardware Security Module (HSM) for private keys
    • Or cloud HSM (AWS CloudHSM, Azure Key Vault)
    • Never commit keys to source control
  3. Test Thoroughly

    • Verify signatures with multiple validators
    • Test on different file formats
    • Check cross-platform compatibility
  4. Monitor & Maintain

    • Implement certificate rotation
    • Monitor for revocations
    • Keep SDKs updated

Key Integration Points:

Your App Workflow:
1. Content Creation/Upload
2. [Add C2PA Manifest] ← Your integration point
3. Sign with Certificate
4. Save/Publish Signed Content
5. [Optional] Verify on Display ← Another integration point

Typical Integration Time:

  • Simple verification: 1-2 days
  • Basic signing: 3-5 days
  • Full production deployment: 2-4 weeks

Testing (Free):

  • Self-signed certificates
  • Good for development only
  • Not trusted by validators

Production:

Get Help:

Contribute:


Terminal window
c2patool image.jpg
Terminal window
c2patool input.jpg \
--manifest manifest.json \
--signer-cert cert.pem \
--signer-key key.pem \
--output signed.jpg
https://contentcredentials.org/verify
{
"claim_generator": "app-name/version",
"assertions": [
{
"label": "stds.schema-org.CreativeWork",
"data": {
"author": [{"name": "Creator Name"}]
}
}
]
}

  • File may not have C2PA manifest
  • Metadata may have been stripped
  • Try different file format
  • File modified after signing
  • Certificate revoked or expired
  • Trust chain broken
  • Using self-signed cert (expected for testing)
  • CA not in trust list
  • Add custom trust anchors if needed
  • C2PA adds ~10-50KB per manifest (minimal)
  • Signing takes less than 1 second for typical files
  • Verification is nearly instant

Ready to start? Pick your method above and dive in!

Questions? Check the FAQ or open an issue.


*Last updated: November 2025