C2PA Content Credentials
Read the C2PA Content Credentials in a media file: verify the signature and show the tool that made it, the signer, edits, and any AI-generation flags.
c2pa-inspect Example
{
"has_c2pa": true,
"bytes_size": 184320,
"media_type": "image/jpeg",
"source_url": "https://example.com/photo.jpg",
"manifest_count": 1,
"active_manifest": {
"label": "urn:uuid:1234...",
"title": "photo.jpg",
"format": "image/jpeg",
"signer": {
"time": "2024-06-15T10:30:00Z",
"issuer": "C=US, O=Adobe Inc., CN=Adobe Photoshop CS Test Cert"
},
"vendor": "Adobe",
"assertions": [
{
"kind": "Json",
"label": "c2pa.actions"
},
{
"kind": "Json",
"label": "c2pa.hash.data"
}
],
"ai_generated": false,
"claim_generator": "Adobe Photoshop 25.0",
"signature_valid": true,
"assertions_count": 4,
"ingredients_count": 0
},
"validation_status": []
} Inputs
| Field | Type | Required | What it is |
|---|---|---|---|
url | string | Yes | HTTP(S) URL of an image (JPEG, PNG, WebP, AVIF, HEIF, TIFF, DNG) to inspect for C2PA manifests |
Output fields
How reliably each field appears in a successful answer.
| Field | Type | Appears |
|---|---|---|
has_c2pa | boolean | Always (present in every successful answer) |
bytes_size | integer | Always (present in every successful answer) |
media_type | string | Always (present in every successful answer) |
source_url | string | Always (present in every successful answer) |
manifest_count | integer | Always (present in every successful answer) |
active_manifest | object or null | Usually (present for most inputs) |
validation_status | array | Always (present in every successful answer) |
How to call it
The same tool through each route. MCP clients reach it through Strale’s server at https://api.strale.io/mcp; the call below is what the agent sends.
# Needs an API key. max_price_cents caps what this call may cost.
curl -X POST https://api.strale.io/v1/do \
-H "Authorization: Bearer $STRALE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"capability_slug": "c2pa-inspect",
"inputs": {
"url": "https://raw.githubusercontent.com/contentauth/c2pa-rs/main/sdk/tests/fixtures/CA.jpg"
},
"max_price_cents": 10
}' {
"tool": "strale_execute",
"arguments": {
"slug": "c2pa-inspect",
"inputs": {
"url": "https://raw.githubusercontent.com/contentauth/c2pa-rs/main/sdk/tests/fixtures/CA.jpg"
},
"max_price_cents": 10
}
} import { Strale } from "straleio";
const strale = new Strale({ apiKey: process.env.STRALE_API_KEY! });
const result = await strale.do({
capability_slug: "c2pa-inspect",
inputs: {
"url": "https://raw.githubusercontent.com/contentauth/c2pa-rs/main/sdk/tests/fixtures/CA.jpg"
},
max_price_cents: 10,
}); import os
from straleio import Strale, DoRequest
strale = Strale(api_key=os.environ["STRALE_API_KEY"])
result = strale.do(DoRequest(
capability_slug="c2pa-inspect",
inputs={
"url": "https://raw.githubusercontent.com/contentauth/c2pa-rs/main/sdk/tests/fixtures/CA.jpg",
},
max_price_cents=10,
)) # No account. The first request answers 402 with the price in USDC;
# an x402 client pays it from your wallet and repeats the request.
curl -i -X POST https://api.strale.io/x402/v2/c2pa-inspect \
-H 'Content-Type: application/json' \
-d '{
"url": "https://raw.githubusercontent.com/contentauth/c2pa-rs/main/sdk/tests/fixtures/CA.jpg"
}' Limitations
Images only; video and audio are not supported
Supports JPEG, PNG, WebP, AVIF, HEIF, TIFF, DNG and GIF images. Video and audio formats, including MP4, M4A, MP3 and WAV, are not supported.
What to do instead: Convert the relevant frame to a still image before inspection.
15 MB per-fetch size cap
Fetched media is limited to 15 MB. Supply a smaller derivative or downsampled image for larger originals.
What to do instead: Provide a publicly accessible URL for a downsampled image.
Public HTTP or HTTPS URL required
Accepts only publicly accessible HTTP or HTTPS URLs. Direct uploads and base64-encoded media are not supported.
What to do instead: Host the media on a publicly accessible URL (e.g. S3 public object, CDN) before calling.
Unlisted signers can report as untrusted
`signature_valid` checks cryptographic verification against the tool’s bundled trust list; a valid signature from an unlisted signer can still report untrusted in `validation_status`. Assess `signer.issuer` together with `signature_valid`.
What to do instead: Inspect validation_status for codes ending in ".untrusted" and decide whether to trust the signer organisation separately.
AI-generation flag is heuristic, not authoritative
ai_generated returns true if any manifest assertion label matches a known generative-AI marker (c2pa.training-mining, com.adobe.generative-ai, etc.). C2PA does not yet have a single canonical "this content is AI" assertion, so absence of the flag does not prove the content is human-made.
What to do instead: For high-stakes decisions, also inspect the assertions array for vendor-specific generative-AI labels not in the built-in list.