Skip to main content
Sandbox receipts are signed test JWS objects. COSE serialization and embedded-manifest verification below are target contract features. Use the quickstart for the supported JSON/JWS flow; test receipts do not authorize real talent content.
Every decided check and generation has a receipt: a signed statement of what Reflections decided, under which licenses, about which request or bytes. A receipt verifies offline against the published keys and never expires. Its live status, which a revocation can change, is at GET /v1/receipts/{receipt_id}. A receipt comes in two forms with the same claims: a compact JWS (jws), and a COSE_Sign1 structure (cose) for tools that work in CBOR.
typ is always tlp-receipt+jwt. A receipt has no exp and no aud: it is a record anyone may check, not a credential.

Claims

Example payload

The receipt for a line of speech in Maya Okafor’s voice, generated by Northlight under its own voice license for branded content on audio and the web in the US, and allowed after its generation check:
Northlight holds this license itself, so platform and licensee are the same account. A check receipt has kind: "check", a chk_ subject and no artifact_sha256. A deny has a receipt too, so a platform can prove it refused. This example is unbound. Had Northlight declared its C2PA claim-signing certificate, tlp would also carry, and the receipt object would repeat as c2pa_signer:

COSE form

cose on the receipt object is a base64 COSE_Sign1 structure (RFC 9052, CBOR tag 18) carrying the same claims: In CBOR diagnostic notation:
The payload is the same bytes as the JWS payload, which for this receipt begin {"iat":1792260363,"iss":"https://app.reflections.ai",. To verify it, build the Sig_structure ["Signature1", protected, h'', payload], encode it as CBOR, and verify the signature over those bytes with the JWKS key whose kid matches. The payload then parses as the same JSON claims as the JWS.

Verify a receipt

1

Check the header

alg is ES256 and typ is tlp-receipt+jwt. A receipt with a kid that starts with rfl-test- was made in test mode and proves nothing about live content.
2

Check the signature

Verify it against the key with the same kid in the JWKS. Retired keys stay published, so an old receipt keeps verifying. Do not reject a receipt for its age.
3

Check the claims

iss is https://app.reflections.ai. Read tlp.decision, tlp.assurance, tlp.talent and tlp.use to see what was decided and on what evidence. Each entry in tlp.licenses names the signed revision behind one talent’s license. A party that can read the license, such as the licensee, compares each entry’s terms_digest with the terms_digest of the revision it names, from GET /v1/licenses/{license_id}/revisions/{revision_id}.
4

Match it to the content

tlp.artifact_sha256 is the digest of the bytes the platform submitted, before it embedded the C2PA manifest, so a delivered file has a different digest. To match a file to its receipt, send the file to POST /v1/verifications, which reads an embedded manifest first, then matches by exact digest, then by fingerprint and watermark. For a receipt read from a manifest, compare tlp.c2pa_signer.thumbprint with the SHA-256 of the manifest’s claim signer certificate (DER). A receipt without tlp.c2pa_signer proves the decision, not that this file carries it (TLP-RCP-16).
5

Read the live status

The signature proves a past decision. Whether the output may still be used is in use_status from GET /v1/receipts/{receipt_id}.

Live status

The receipt object lists the same licenses as the signed tlp.licenses, with one difference in spelling: each entry names its revision license_revision, where the claim names it revision. Anyone can read a receipt, with any key or none, and see it as a page at https://app.reflections.ai/r/{receipt_id}. Discovery publishes that template as receipt_page; receipt_endpoint remains the JSON route at /v1/receipts/{receipt_id}. A test page is explicitly fictional and grants no production rights. An unavailable human page contains no receipt facts; protocol clients use the JSON endpoint’s HTTP 503 response.

C2PA assertion

Where the receipt goes in the output’s manifest.

Verifying content

Verification by receipt, manifest or file.

Provenance

Receipts, manifests, fingerprints and verification.

Receipts in the Standard

Receipt format, signing keys and key rotation.