Skip to main content
Sandbox and protocol reference. Send a SHA-256 digest, optionally with inline base64 data. The sandbox accepts at most 7 MiB of decoded bytes in a 10 MiB JSON request body. It does not store files, fetch URLs or evaluate image, audio or video content. Start with the runnable quickstart and sandbox support matrix.
A check allows a request. A generation decides whether the output that request produced may be delivered. Reflections binds the bytes to the check by their SHA-256 and checks the license’s rules on them, for the talent the check covered. Deliver nothing until the generation’s decision is allow.

What to submit

The check’s generation_check obligation says how much to submit: Submit the bytes you deliver. If you resize, re-encode or draw a label into an image, do it before you submit, so the bytes Reflections checks are the bytes your user receives. The C2PA manifest is added after the decision; see Embed provenance.

Send bytes in the sandbox

Use artifact.data with artifact.sha256 for up to 7 MiB decoded bytes, keeping the entire JSON body within 10 MiB. A digest-only submission is attested. The sandbox does not fetch artifact.url, and artifact.file is rejected. Neither path evaluates the media’s content.

Planned file-upload contract

The limits and upload examples below are protocol targets. File storage, URL fetches and the 10 MB inline target are not implemented by the current sandbox. For the JSON upload, upload_url expires in 1 hour. Use the file once its status is ready. Files expire after 24 hours unless a held generation needs them longer.

Bind the output to its check

Create one generation per candidate. Name the check, the candidate_index (from 0 up to the check’s execution.candidates minus one), and the sha256 of the bytes.
Send it to POST /v1/generations with an Idempotency-Key, as in the quickstart. Optional fields:

Read the decision

Images, speech up to 60 seconds and text return a decision in the response. Video and longer audio return status: "checking", and the decision arrives as generation.allowed or generation.denied.

Findings

findings lists each rule checked on the bytes and its result:
  • preserved: the rule holds. violated: it does not, and the output is withheld.
  • unchecked: the check could not read this rule. A rule the talent wrote that is unchecked does not withhold the output; it is delivered and listed in unchecked_terms. A protected attribute such as identity.samePerson that cannot be read withholds the output.
  • assurance: "observed" means Reflections checked these bytes.
A denied generation still has a receipt. It records the decision; it is not something to embed.

Which talent are checked

Reflections checks an output only for the talent its check covered. It does not match the output against anyone else, so the check must cover every talent the request invokes. Name each talent your user picks, and send references and voice samples as inputs; see Resolve talent. Every generation names a check, or a session for an output made in a live session.

Errors

A timeout leaves the outcome unknown. Retry with the same Idempotency-Key. A new key for a candidate that already has a generation returns 409 generation_already_submitted.

Test it

Put rfl_test_rule_violated, rfl_test_identity_changed, rfl_test_unchecked or rfl_test_async in the generation’s transcript to force each result in test mode.

Generation checks

What is checked on the bytes, and for which talent.

Embed provenance

Put the receipt in the output’s C2PA manifest.

Handle escalations

Held outputs and releases.

Create a generation

The endpoint reference.