Skip to main content
This page specifies the receipt a license server signs for each decision, its JWS and COSE forms, the algorithm a verifier follows, how signing keys are published and rotated, the live status of a receipt, and the public receipt page.

When a receipt is issued

TLP-RCP-1. A license server MUST sign a receipt for every check and every generation when the decision is allow or deny. An escalated check or a held generation gets its receipt when it resolves. A session’s receipt is the receipt of the check that started it. TLP-RCP-2. A receipt MUST NOT change once signed. A later change in what is permitted is reported through the receipt’s live status, never by altering or re-signing it.

JWS form

The header is { "alg": "ES256", "kid": "<key ID>", "typ": "tlp-receipt+jwt" }. A receipt has no exp and no aud: it is evidence for anyone, and it does not expire. TLP-RCP-3. A license server MUST sign receipts as JWS Compact Serializations with ES256 and the header and claims above, and MUST NOT include an end-user identifier, prompt text or input media in a receipt.

Example (informative)

The receipt for a line of speech in Maya Okafor’s voice that Northlight generated under its platform license, for branded content on audio and the web in the US:

COSE form

TLP-RCP-4. A license server MUST also make each receipt available as a tagged COSE_Sign1 structure (RFC 9052, CBOR tag 18) carrying the same claims:
Both forms carry the same payload bytes, so a verifier can check either and read the same claims. The Talent API returns the JWS as jws and the COSE form as cose on the receipt object.

Verifying a receipt

TLP-RCP-5. A verifier MUST follow these steps, and MUST treat the receipt as unverified when any step fails:
1

Get the receipt

Read it from the output’s C2PA assertion, from the receipt endpoint (jws), or from a verification result.
2

Check the header

alg MUST be ES256 and typ MUST be tlp-receipt+jwt.
3

Choose the issuer

Read iss from the payload. Decide whether you trust that license server. Fetch its discovery document at iss followed by /.well-known/talent-license, confirm its issuer equals iss, and take its jwks_uri.
4

Verify the signature

Find kid in that JWK Set, fetching it once more if kid is unknown, and verify the signature. Reject when the key is not found.
5

Check the content

iat MUST NOT be later than the current time plus 60 seconds. tlp.ver MUST have major version 1. Do not check for expiry: receipts do not expire.
6

Relate it to the content

For a generation receipt, relate the receipt to the file you hold: by tlp.artifact_sha256, by the C2PA manifest’s binding, or by a verification lookup, as C2PA specifies. A receipt that you cannot relate to the file proves nothing about it. A receipt read from a manifest is related to it only as TLP-RCP-16 allows.
7

Read what it proves

tlp.decision and tlp.assurance say what was decided at iat and what the license server observed. tlp.licenses names the signed revision behind each talent’s license; to rely on those terms, compare each entry’s terms_digest with that revision’s, as TLP-TOK-5 requires. For what is permitted now, read the live status.

Binding to a C2PA claim signer

Anyone who holds a receipt can copy its assertion into a manifest for other content. The tlp.c2pa_signer claim lets a verifier detect that. TLP-RCP-15. A license server MUST include tlp.c2pa_signer in a generation receipt when the generation request declared c2pa_signer, with the thumbprint as declared, and MUST NOT include it otherwise or in a check receipt. The license server records the platform-declared thumbprint as given and does not check it against a certificate. TLP-RCP-16. A verifier that reads a receipt from a C2PA manifest’s assertion MUST, when the receipt has tlp.c2pa_signer, compute the SHA-256 of the DER encoding of that manifest’s claim signer certificate and treat the assertion as unrelated to the file unless it equals tlp.c2pa_signer.thumbprint. A verifier MUST treat an assertion whose receipt has no tlp.c2pa_signer as unbound: evidence of a decision, not of this file, unless a lookup relates them (TLP-C2PA-8). The thumbprint names the certificate, not the file. A verifier still validates the claim signature and its bindings to the file, as TLP-C2PA-8 requires.

Signing keys and rotation

TLP-RCP-6. A license server MUST publish its signing keys as EC P-256 keys in a JWK Set at the jwks_uri of its discovery document, served over HTTPS with a Cache-Control max-age. TLP-RCP-7. A license server MUST publish a new key at least 30 days before it signs anything with it, and MUST never reuse a kid. The Talent API names live keys rfl-YYYY-MM and test keys rfl-test-YYYY-MM, such as rfl-2026-10-docs3. TLP-RCP-8. A license server MUST keep a retired key in its JWK Set for as long as it retains any receipt the key signed, so that old receipts keep verifying offline. TLP-RCP-9. When a signing key is compromised, a license server MUST stop signing with it, remove it from its JWK Set, keep serving the live status of every receipt it signed, and publish the compromise and its time window. A verifier MUST then confirm such a receipt through the receipt endpoint instead of offline. TLP-RCP-10. A license server MUST sign test-mode receipts with test-mode keys and report them with livemode: false at the receipt endpoint. A verifier MUST NOT accept a test-mode receipt as evidence of a live license.

Live status

A receipt proves what was decided when it was signed. Its live status says what use of the output is permitted now. TLP-RCP-11. A license server MUST serve each receipt and its current use_status, with use_status_changed_at, at the receipt_endpoint of its discovery document, to anyone who has the receipt ID, with or without credentials. It MAY rate-limit requests without credentials; the Talent API allows 10 per minute per IP address. TLP-RCP-12. A license server MUST change use_status only for the events in the table. A revocation with post_revocation retain leaves it permitted until the window ends. TLP-RCP-13. A verifier that decides whether an output may be placed or kept MUST read the live status first, and MUST NOT rely on offline verification alone for that decision. use_status is meaningful only for a receipt whose decision is allow, and is null on a deny receipt. A verifier MUST ignore it on a deny receipt.

Receipt pages

TLP-RCP-14. A license server MUST serve a human-readable page for each receipt at the receipt_page URL template of its discovery document, such as https://app.reflections.ai/r/rcpt_hk5zba2q8v1m3n7p4r6s9t0wxy. The page MUST show the decision, the kind, the assurance, the talent’s name, the licensee’s and platform’s names, the use, the time of the decision, the current use_status and, for a generation, the artifact’s SHA-256. It MUST NOT show prompt text, inputs, the end-user claim or compensation.

Receipt format

The receipt object in the Talent API.

C2PA

Where the receipt goes in a manifest, and what survives stripping.

Revocation

The events that change a receipt’s live status.

Retrieve a receipt

The receipt endpoint.