Sandbox and protocol reference. Signed test receipts and exact-digest lookup are available.
Hosted C2PA parsing, fingerprints, watermarks and production revocation status remain planned.
A test receipt grants no rights over real talent.
Start with the runnable quickstart and sandbox support matrix.
Receipts
A receipt is a compact JWS signed with ES256, withtyp tlp-receipt+jwt and no expiry. It
records:
The same receipt is also issued as a COSE_Sign1 structure (alg ES256,
-7) with the same claims as
its JSON payload, for embedding where COSE is expected. The full format is on
Receipt.
Signing keys
Receipts are verified against the keys athttps://app.reflections.ai/.well-known/jwks.json:
EC P-256 keys with kid values such as rfl-2026-10-docs3 (live) and rfl-test-2026-10-docs3 (test). A new key
is published 30 days before it signs anything, retired keys stay published so old receipts keep
verifying, and a kid is never reused.
Live status
A receipt’s signature proves what was decided. Itsuse_status says what use is permitted now:
Read it with
GET /v1/receipts/{receipt_id}, with any
key or with none at the public rate limit. The current endpoint returns JSON at
https://app.reflections.ai/v1/receipts/{receipt_id}. A receipt stays valid evidence that an output was
licensed when it was made, even after a revocation changes its use_status.
The C2PA assertion
An allowed generation returns ac2pa object:
label, along with the standard
c2pa.actions assertion recording the IPTC digital source type trainedAlgorithmicMedia. Your
platform stays the C2PA claim signer for its own output. Because the receipt inside is signed by
Reflections, it verifies independently of your signature. See
Embedding provenance and the
C2PA specifications.
When metadata is stripped
A C2PA manifest survives only where the file keeps its metadata, and many upload pipelines strip it. Verification by file covers that: Reflections matches the file by its exact digest first, then by fingerprint, so it still finds the receipt after metadata is removed or the file is re-encoded. Reflections keeps each allowed output’ssha256 and fingerprint for the license term plus 3 years.
If you also apply a watermark, register it on the generation with
watermark: { "algorithm": "…", "id": "…" } so verification can join the two. Reflections does
not require any particular watermark.
Verification
POST /v1/verifications takes exactly one of a
receipt (ID or JWS), a C2PA manifest, a url, a sha256, a fingerprint, or the file itself.
These are the protocol methods. The current sandbox accepts only receipt or sha256, and a test
receipt needs a test key; see the verification table. Digest lookup is limited to your account; a known receipt ID can be read
without a key at GET /v1/receipts/{receipt_id}.
method says how the match was made: receipt, manifest, digest, fingerprint or
watermark. match.exact says whether the bytes match the registered digest, and manifest
reports the C2PA claim signer, whether the assertion is present, and whether its signature is
valid. Test receipts verify only with a test key.
Assurance
Every receipt states itsassurance:
observed: Reflections checked these bytes, or read these inputs.attested: Reflections recorded what you stated, such as text you sentwithheld.
Example: verifying a voice line
A podcast host receives an audio file that claims to be a licensed line in Maya Okafor’s voice. The host reads the receipt ID from the file’s manifest and verifies it:Related
Embedding provenance
Writing the assertion and the disclosure label.
Verifying content
Verification by receipt, manifest or file.
Distribution platforms
Verifying on upload and reading live status.
C2PA assertion
The
ai.reflections.license format.