Content Provenance Checks
Check whether an image or audio file carries known OpenAI provenance signals: a C2PA content-credentials manifest or a SynthID watermark.
See the official Content Provenance documentation.
Usage
//! Content provenance check: does a file carry OpenAI C2PA / SynthID signals?
//!
//! Run with: OPENAI_API_KEY=sk-... cargo run --example content_provenance -- photo.jpg
use openai_oxide::OpenAI;
use openai_oxide::types::content_provenance::ContentProvenanceResult;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let path = std::env::args()
.nth(1)
.ok_or("usage: content_provenance <image-or-audio-file>")?;
let client = OpenAI::from_env()?;
let check = client.content_provenance_checks().from_path(&path).await?;
for result in &check.results {
match result {
ContentProvenanceResult::C2pa(c2pa) => {
println!(
"C2PA: {:?} (validation: {:?}, issuer: {:?})",
c2pa.outcome, c2pa.validation_state, c2pa.issuer
);
}
ContentProvenanceResult::SynthId(synthid) => {
println!(
"SynthID: {:?} (model: {:?})",
synthid.outcome, synthid.model
);
}
ContentProvenanceResult::Other(value) => {
println!("Unknown result type: {value}");
}
}
}
Ok(())
}
From bytes instead of a path:
use openai_oxide::types::content_provenance::ContentProvenanceCheckParams;
let params = ContentProvenanceCheckParams::new(bytes, "photo.jpg");
let check = client.content_provenance_checks().create(params).await?;
Interpreting results
not_detected does not prove human origin. The signal may be missing because:
- the metadata was stripped or shows evidence of tampering,
- the watermark degraded,
- the file came from a legacy generation model or predates provenance signals,
- the file was generated by another company’s model, which this tool does not detect.
results is a Vec<ContentProvenanceResult> — one entry per signal type
(C2pa, SynthId), plus Other for result types added after this release.