Skip to main content
Production protocol reference. The sandbox binds submitted bytes to their SHA-256, then uses deterministic fixture rules and test markers. It does not inspect media for identity or content compliance. File uploads and webhook delivery remain planned. Start with the runnable quickstart and sandbox support matrix.
A generation is an output submitted to POST /v1/generations before anyone sees it. It names the check the output was made under, and Reflections checks that license’s rules on the actual bytes. Deliver nothing until the generation’s decision is allow.

Binding the output to its check

A generation names its check and the candidate_index of the output among the check’s candidates, sends the bytes as an artifact, and declares their sha256. The digest goes into the receipt. The talent’s rules are about content, so Reflections checks the bytes themselves.
  • If the bytes do not match the declared sha256, the call fails with 422 artifact_digest_mismatch.
  • A second generation for the same check and candidate fails with 409 generation_already_submitted, so unrelated bytes cannot ride a valid check.
  • A check that is not allow refuses generations with 409 check_not_allowed.
Send execution.job_id, the provider’s ID for the job, so the output can be traced to the run that made it. The sandbox accepts base64 data up to 7 MiB decoded bytes in a 10 MiB JSON body, or an attested SHA-256 digest. File IDs, URL fetching and the protocol’s 10 MB inline target remain planned.

What is checked on the bytes

Reflections transcribes speech in every output. Send transcript if you have it; it does not replace the transcription.

Findings

Each rule checked becomes a finding:
A rule the talent wrote that could not be read is unchecked: the output is delivered and the term is listed in unchecked_terms, so the record shows it was not checked. A protected attribute, such as identity.samePerson, is never delivered unchecked: an output whose protected attributes cannot be confirmed is denied.

When the decision arrives

Images, speech up to 60 seconds and text return their decision in the response. Video and longer audio return status: "checking", and the decision arrives as generation.allowed or generation.denied. Under a license with release_policy: "per_output_review", a passing output returns escalate and stays held until a reviewer releases it. Video and longer audio under such a license return held at once: the reviewer is asked only after the output passes its checks, and a failure arrives as generation.denied. Deliver only on allowed and released. Withdraw a held output you no longer need with POST /v1/generations/{generation_id}/withdraw; its delivery returns to the license’s delivery limit.

Which talent are checked

An output is checked only for the talent its check covered. Reflections does not match it against other talent, and does not look for talent nobody named. A check whose inputs invoke no protected talent returns allow with talent: [] and no obligations, so its outputs need no generation. A talent or representative who finds an output of the talent’s likeness can verify it. A verified receipt names the license the output was made under.

Example: a held image for Ridgeline

Maya Okafor releases each output under Ridgeline’s license. A passing image comes back held:
Every rule held, so the output waits only for Maya Okafor. When she releases it, you receive generation.released with status: "released", decision: "allow", the receipt and the c2pa assertion to embed.

Submitting outputs

Uploads, candidates, digests and findings.

Escalation

Release review and expiry.

What we enforce

Observed and attested assurance.

Provenance

The receipt and the C2PA assertion.