Sandbox and protocol reference. Test receipt IDs, signed test receipts and exact SHA-256
digests are supported. File uploads, URLs, manifests, fingerprints and watermarks below are
planned verification methods, not currently runnable examples.
Start with the runnable quickstart and sandbox support matrix.
POST /v1/verifications needs a test key (see the verification table) and accepts a test receipt ID, signed test
receipt or exact SHA-256 digest. Digest lookup searches your account’s receipts. Reading a known
receipt at GET /v1/receipts/{receipt_id} needs no key. These test results grant no production rights.
Protocol verification methods
Send exactly one of these toPOST /v1/verifications:
A file that carries a manifest is verified through it, as in the example below. Otherwise it is
matched by its exact digest, then by fingerprint and watermark, so verification still works after
metadata is stripped or the file is re-encoded.
method says which one matched.
Authorization for your account’s limits.
Read the result
receipt.licenses has one entry per talent whose license applied: the license, the signed
license_revision and its terms_digest.
For a fingerprint match, match.exact is false and match.confidence is high or medium.
A medium match is weaker evidence; show it as such.
For a manifest match, manifest.signer is the C2PA claim signer, normally the platform that
generated the output. signature_valid is that signature’s result. The receipt inside is checked
separately, against Reflections’ keys.
Read the live status
A receipt never changes, but what may be done with the content can.receipt.use_status says what
use is permitted now:
use_status_changed_at says when it last changed. To read the current status of a receipt you
already hold, call GET /v1/receipts/{receipt_id},
or send the ID as receipt. For sandbox verification, use your test key and export RECEIPT_ID
to an ID returned by your generation, such as the one saved by the quickstart:
https://app.reflections.ai/r/{receipt_id}, also published as
receipt_page in discovery. GET /v1/receipts/{receipt_id} remains the JSON endpoint. Neither
requires a key. Test pages are labelled fictional and grant no production rights. If verification
is unavailable, the human page shows an unavailable state; the JSON endpoint returns HTTP 503.
Verify a receipt offline
The receipt is a compact JWS (receipt.jws, or data.receipt in the C2PA assertion). You can
verify it without calling Reflections:
1
Find the key
Read
kid from the JWS header and find it in https://app.reflections.ai/.well-known/jwks.json.
Cache the JWKS for its Cache-Control max-age, and refetch once if the kid is unknown.
Retired keys stay published, so old receipts keep verifying.2
Check the signature and header
The algorithm is ES256 and
typ is tlp-receipt+jwt. iss is https://app.reflections.ai.
A receipt has no exp.3
Read the claims
tlp.kind, tlp.decision, tlp.assurance, tlp.talent and tlp.licenses say what was
decided and under which signed terms. Each tlp.licenses entry names a talent’s license, the
signed revision and its terms_digest; the licensee can compare that digest with the
revision’s own terms_digest. For a generation, tlp.artifact_sha256 is the digest of the
bytes the platform submitted, before it embedded the manifest.use_status for that. The
receipt format lists every claim.
What can go wrong
assurance matters. observed means Reflections checked the bytes. attested means it recorded
what the platform stated, such as text sent withheld, and never inspected that content.Related
Distribution platforms
Verify uploads and act on live status.
Provenance
Receipts, manifests and fingerprints.
Receipt format
JWS and COSE forms, and every claim.
Embed provenance
Write the receipt into a C2PA manifest.