MagicTools
AI TutorialsBy CooconAugust 16, 202618 views7 min read

OpenAI Content Provenance API: C2PA and SynthID in One Call

The topic of content provenance has moved from standard documents into various products over the past year: Anthropic added watermarks and C2PA signatures to Claude's outputs, Google launched SynthID, and industry verification tools have gradually become more complete. OpenAI recently added its own piece to the puzzle—the Content Provenance API: a synchronous interface where uploading a file returns "whether this content carries OpenAI's provenance signals".

This article will break down the API details and field semantics clearly, focusing on a few points in the official documentation that are easily misinterpreted.

What the API Does: Dual-Signal Check

Upload an image or audio file to POST /v1/content_provenance_checks. The API checks two types of signals simultaneously:

Signal Applicable Media What It Checks Characteristics
C2PA Content Credentials Images Embedded signature metadata in the file (issuer, AI generation markers) Information-rich, but editing/forwarding/re-saving strips it
SynthID Images + Audio Watermarks directly embedded in pixels/waveforms Less information, but resilient to some transformations

The two signals—one fragile, one robust—complement each other. This is precisely the "metadata + pixel watermark dual-track" approach we mentioned in the "C2PA Content Credentials Verification Guide" realized as a product.

The call is synchronous: the response is the result, no need to create background tasks, poll, or use the Files API first. If you don't want to write code, the official web version is also available at openai.com/verify.

curl https://api.openai.com/v1/content_provenance_checks \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F "file=@./example.png;type=image/png"

Python SDK (2.52.0+):

from openai import OpenAI

client = OpenAI()

with open("./example.png", "rb") as image:
    result = client.content_provenance_checks.create(
        file=("example.png", image, "image/png"),
    )

Return Structure and Field Semantics

A typical response for an image:

{
  "object": "content_provenance_check",
  "created_at": 1778000000,
  "results": [
    {
      "type": "c2pa",
      "outcome": "detected",
      "validation_state": "trusted",
      "issuer": "OpenAI OpCo, LLC",
      "model": "gpt-image",
      "generated_at": "2026-07-27T18:34:12Z"
    },
    {
      "type": "synthid",
      "outcome": "not_detected",
      "model": null,
      "generated_at": null
    }
  ]
}

Several design details are worth noting:

  • There is no top-level outcome. An image returns two results: C2PA + SynthID; audio only returns one: SynthID. Each must be interpreted independently; the API does not summarize "is/is not AI-generated" for you.
  • Inapplicable checks are omitted directly, rather than returning not_detected—when parsing, search by type, do not access by index.

C2PA Result: "detected" Criteria Are Stricter Than Expected

For outcome to be detected, three conditions must be met simultaneously: the manifest's validation_state is trusted or valid, the issuer is OpenAI, and the manifest contains an AI generation action. If any condition fails—a manifest issued by a third party, a manifest without an AI generation action, an invalid (signature verification failed) or not_present (no manifest) state—the result is not_detected.

This means an important interpretation technique: when outcome is not_detected, the issuer and validation_state fields may still contain information. For example, an image signed by Adobe Firefly will have an outcome of not_detected (not signed by OpenAI), but issuer will tell you who signed it. Looking only at the outcome misses this information.

The four-tier semantics of validation_state are consistent with c2pa-rs: trusted (signature valid and certificate trusted), valid (signature valid but certificate not on the trust list), invalid (verification failed, cannot be used as provenance evidence), not_present (no manifest). The difference between valid and invalid was explored with a real-world pitfall case in our C2PA guide—signature validity and issuer trust are two independent dimensions; do not mix them.

SynthID Result

The semantics are much simpler: detected means a supported watermark was identified; not_detected only means none was detected, it does not rule out the content being AI-generated or AI-modified. model and generated_at are provided if available, otherwise null.

Supported Formats and Limitations

  • Images: PNG, JPEG, WebP
  • Audio: MP3, Opus, AAC, FLAC, WAV, PCM; decoded duration ≤ 60 seconds. For Opus, set the media type to audio/ogg.
  • Single file ≤ 50 MiB, one file per request
  • Error Codes: 400 for unsupported/corrupted file format; 404 for organization lacking access; 429 for rate limit exceeded (includes Retry-After)
  • Rate limits are strict; officials state this is to prevent abuse. Higher quotas require a separate application and case-by-case approval.
  • Does not apply to Zero Data Retention—note this for scenarios with strict data residency requirements.

Boundaries Set by OpenAI (More Important Than the API Itself)

The documentation contains a usage guidance section with a very restrained attitude, worth quoting verbatim:

  1. It is not a general-purpose AI detector. It only recognizes OpenAI's own signals and cannot detect content generated by models from other companies—not_detected neither proves "content is human-written" nor "not AI-generated".
  2. The list of reasons for not_detected is long: metadata stripped, watermarks degraded by compression/cropping/screenshots/format conversion, content from an older model before signals were added, or the format itself unsupported. Verification with the original file yields more meaningful conclusions.
  3. Check the issuer before attribution. Detecting a C2PA manifest does not equal OpenAI generation; manifests from third parties should be attributed by issuer.
  4. High-risk scenarios require manual review; do not treat automated results as final judgment.
  5. Repeated querying to reverse-engineer, remove, or circumvent watermarks is explicitly prohibited.

This straightforwardness aligns with Anthropic's stance in Claude's watermark documentation (see "What is Claude's Invisible Watermark"): provenance signals are one-way weak evidence—detection confirms a specific fact, while non-detection confirms nothing. The industry is remarkably uniform in not exaggerating on this point.

When to Use It, When Not To

Suitable for: Adding a layer of definitive evidence for "suspected AI images/audio" in content moderation pipelines, image verification in newsrooms, platforms labeling AI-generated content, and trust & safety workflows.

Not suitable/unnecessary for:

  • Determining whether any arbitrary content is AI-generated—it only covers OpenAI signals, and there is currently no reliable universal answer to this question.
  • Only wanting to see the C2PA credentials of an image—no API key or rate quota needed; use a browser-based local verification tool in ten seconds: MagicTools C2PA Verifier runs signature verification locally via WASM, files are not uploaded, and it works for any issuer—OpenAI, Claude, Adobe, or cameras.
  • Checking text watermarks—this API only accepts images and audio. For the current state of text watermarking (character-level steganography can be checked; statistical watermarks await official detectors), see "AI Text Invisible Watermark Detection Guide".

Common Questions FAQ

Can the Content Provenance API detect images generated by Midjourney, Claude, or Stable Diffusion?

No, it cannot return detected. The API only recognizes OpenAI's own C2PA signatures and watermark signals. However, for images with third-party C2PA manifests, the issuer and validation_state in the response will still describe that manifest—you can know "this was signed by Adobe", just not with a detected outcome.

Does this API cost money? How do I get access?

The endpoint is available to authorized organizations, with strict rate limits. Higher quotas require an application via the official form and case-by-case approval. For specific billing, refer to OpenAI's official pricing page. Note that it does not apply to the Zero Data Retention policy.

Can not_detected prove an image is not AI-generated?

No. Metadata stripping, watermark degradation, products from older models, or generation by other vendors' models will all result in not_detected. Officials explicitly state it is "evidence of non-detection", not "proof of human creation".

What's the difference in the response for images versus audio?

Images return two results: C2PA and SynthID; audio only returns one: SynthID. The API omits inapplicable checks; parse by matching the type field, do not assume a specific array length.

Is there a way to verify without writing code?

Yes, there are two: OpenAI's official web version at openai.com/verify (checks OpenAI's dual signals), and the MagicTools C2PA Verifier (browser-based local verification, works for any issuer, files not uploaded). The latter is faster for routine image checks; the former is for when SynthID determination is needed.

Related Articles

C2PA Content Credentials: How to Verify AI-Generated Images

What C2PA Content Credentials are and how to verify an image's provenance in your browser for free: reading manifests, issuers and validation_state correctly (with a real pitfall we hit), plus why screenshots and social media uploads strip credentials.

utilityAug 16, 20267 min
18

AI Text Watermark Checker: Detect Hidden Unicode Characters

Six kinds of invisible Unicode characters can watermark or track your text: zero-width spaces, direction controls, variation selectors, tag steganography and more. Learn how to detect and safely remove each one, why emoji trigger false positives, and why character scanning cannot catch statistical AI watermarks like Claude's.

utilityAug 16, 20268 min
17

Debian's Vote on AI Code: All 8 Ballot Options Explained

From August 15–28, 2026, Debian developers vote on GR 2026-002: whether LLM-generated contributions are allowed in Debian. The ballot spans eight proposals, from a full ban written into the Social Contract (requiring a 3:1 supermajority) to no restrictions at all. This guide explains each option, the core arguments on both sides, and compares AI contribution policies across Gentoo, Fedora, QEMU, curl, the Linux kernel, and more.

developerAug 16, 20269 min
48

Codex 232x GPU Kernel Speedup: The Real Story and Method

The viral '232x kernel speedup with Codex' was a GPU Mode competition entry: 14 days, 1,500+ submissions, 12th place out of 183, measured against a torch.geqrf baseline. We break down the replicable harness—AGENTS.md evidence rules, /goal loops, beam of candidates, a strong advisor model—plus three caveats: overfitting, numerical stability, and reward hacking.

ai-tutorialsAug 16, 20269 min
46

Published by MagicTools