> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reflections.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> The OpenAPI document at /api-reference/openapi.yaml defines the target contract. Its x-reflections-availability field and each operation's availability notice identify supported test and live forms. Do not infer implementation from a schema or code sample. Live keys support account details, reads of the licenses the calling account holds as licensee or issued as talent (GET /v1/licenses?role=issuer), and GET /v1/generations?license=… for the state of outputs under such a license (summaries only: no prompt, reference, bytes or metadata). Live image checks, submissions and receipts are built but not activated: until activation, a live POST /v1/checks or /v1/generations returns 403 live_not_activated, which must not be retried. Discovery and JWKS are at the origin root (https://app.reflections.ai/.well-known/...), not under /v1.
> Three rules hold everywhere: a decision is never an error (deny and escalate are 200 responses, and a live check still evaluating is a 202 with status checking); generate nothing for a named talent without an allow; deliver nothing until the generation is allow.
> The sandbox accepts personal rk_test_ keys. Persist a separate Idempotency-Key and body for each logical /v1 POST; retry an unknown outcome with the same key and body. OAuth and Talent API MCP remain planned.

# Verify content

> **Test mode available. Live mode available when configured.** Source support does not
establish production activation. The initial live implementation accepts JSON with a
receipt ID, receipt JWS or SHA-256. Receipt-ID and JWS verification are public; digest
discovery requires the owning account's live key. The response exposes the signed receipt
and current use status without private request metadata. Sandbox verification requires a
test key. Multipart files, manifests, URLs and fingerprints are unsupported in both modes.
Live verification creates a fresh verification ID on each call; it does not provide the
exact response replay implemented for live check and generation creation.

**Broader protocol contract:** the remaining description and examples include planned
verification forms beyond those supported JSON inputs.

Verifies a file, a C2PA manifest or a receipt, and returns the receipt it matches with its
live status. A file is read for an embedded manifest first, then matched by its exact
digest, then by fingerprint and watermark, so verification still works after metadata is
stripped or the file is re-encoded. `method` says which one matched. Anyone may verify;
without a key the public rate limit applies. Test-mode receipts verify only with a test
key.




## OpenAPI

````yaml /api-reference/openapi.yaml post /verifications
openapi: 3.1.0
info:
  title: Reflections Talent API
  version: '2026-10-15'
  summary: The license server for a person's name, likeness and voice in generative AI.
  description: >
    This document defines the target Talent API contract. Each operation
    declares its current

    test and live availability. Test mode serves a limited fictional sandbox.
    Live keys support

    account details and reading the caller's own licenses. The initial live
    image check,

    submission and receipt implementation is deployed, but requires separate
    live signing

    activation and production acceptance. Start at
    https://docs.reflections.ai/quickstart for test mode.


    The target API lets any product that can generate a real person check
    whether a use is licensed,

    verify the output it made, prove that verification to anyone downstream,
    report usage, and

    honor revocations.


    Protected requests use a secret key in the `Authorization` header. The
    target contract defines test keys

    (`rk_test_…`) and live keys (`rk_live_…`) use the same base URL; the key
    decides the mode.


    A decision is never an error. `deny` and `escalate` are `200` responses that
    carry a decision.

    Errors use RFC 9457 problem details.
  contact:
    name: Reflections developer support
    url: https://docs.reflections.ai/production/support
    email: developers@reflections.ai
servers:
  - url: https://app.reflections.ai/v1
    description: >-
      Fictional test sandbox and conditional live support; availability and
      activation are separate
security:
  - SecretKey: []
tags:
  - name: Account
    description: The account that owns the calling key.
  - name: Talent
    description: >-
      People whose name, likeness and voice are protected and licensed through
      Reflections.
  - name: Facets
    description: >-
      The parts of a talent's identity a license can cover, such as a voice or a
      likeness.
  - name: Resolutions
    description: Find which talent a prompt, image or voice sample invokes.
  - name: Licenses
    description: Signed licenses and their revisions.
  - name: License requests
    description: Ask a talent for a new license or a wider one.
  - name: Connections
    description: A licensee's permission for a platform to use its licenses.
  - name: Files
    description: References and outputs uploaded for checks and generations.
  - name: Checks
    description: Decide whether a use may proceed, before anything is generated.
  - name: Generations
    description: Check an output against the license its check relied on.
  - name: Sessions
    description: Authorize live voice and video with short-lived tokens and sampled checks.
  - name: Receipts
    description: Signed, portable proof of a decision.
  - name: Verifications
    description: Verify a file, manifest or receipt.
  - name: Revocations
    description: Every narrowing of consent, and the platform's acknowledgement of it.
  - name: Usage records
    description: Report usage for settlement and audit.
  - name: Statements
    description: Monthly amounts owed under a license, reconciled against observed usage.
  - name: Mandates
    description: A representative's authority to act for a talent, and its powers.
  - name: Escalations
    description: >-
      The review queue. Checks and held outputs waiting for the talent's side to
      decide.
  - name: License drafts
    description: Terms prepared for a talent's signature. Only a person signs.
  - name: Webhook endpoints
    description: Where Reflections sends events.
  - name: Events
    description: The record of everything that happened to your objects.
  - name: Test helpers
    description: Act as a talent or reviewer in test mode.
  - name: Discovery
    description: The public discovery document and signing keys. Neither needs a key.
  - name: OAuth
    description: >
      Authorization for connections, MCP clients and RSL clients, and the
      metadata that describes it.
paths:
  /verifications:
    post:
      tags:
        - Verifications
      summary: Verify content
      description: >
        **Test mode available. Live mode available when configured.** Source
        support does not

        establish production activation. The initial live implementation accepts
        JSON with a

        receipt ID, receipt JWS or SHA-256. Receipt-ID and JWS verification are
        public; digest

        discovery requires the owning account's live key. The response exposes
        the signed receipt

        and current use status without private request metadata. Sandbox
        verification requires a

        test key. Multipart files, manifests, URLs and fingerprints are
        unsupported in both modes.

        Live verification creates a fresh verification ID on each call; it does
        not provide the

        exact response replay implemented for live check and generation
        creation.


        **Broader protocol contract:** the remaining description and examples
        include planned

        verification forms beyond those supported JSON inputs.


        Verifies a file, a C2PA manifest or a receipt, and returns the receipt
        it matches with its

        live status. A file is read for an embedded manifest first, then matched
        by its exact

        digest, then by fingerprint and watermark, so verification still works
        after metadata is

        stripped or the file is re-encoded. `method` says which one matched.
        Anyone may verify;

        without a key the public rate limit applies. Test-mode receipts verify
        only with a test

        key.
      operationId: createVerification
      parameters:
        - $ref: '#/components/parameters/ReflectionsVersion'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerificationCreate'
            examples:
              receipt:
                summary: A receipt ID, for its live status
                value:
                  receipt: rcpt_hk5zba2q8v1m3n7p4r6s9t0wxy
              fingerprint:
                summary: A fingerprint computed on your platform
                value:
                  fingerprint:
                    perceptual_hash:
                      algorithm: pdq
                      value: >-
                        37e9846ce3ba171f08bf527b156838dec7fd0cb2d474137d16f0b22f6b9dc144
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
      responses:
        '200':
          description: The verification.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimitPolicy'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Verification'
              examples:
                verification:
                  $ref: '#/components/examples/Verification'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '422':
          $ref: '#/components/responses/Unprocessable'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
        '503':
          $ref: '#/components/responses/Unavailable'
        '504':
          $ref: '#/components/responses/Timeout'
      security:
        - SecretKey: []
        - {}
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >
            # Set a unique key once per new action; persist it and reuse it for
            every retry.

            : "${REFLECTIONS_KEY:?Set REFLECTIONS_KEY before running this
            example}"

            : "${REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY:?Set
            REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY before running this
            example}"


            curl --fail-with-body --max-time 30 -X POST
            'https://app.reflections.ai/v1/verifications' \
              -H "Authorization: Bearer $REFLECTIONS_KEY" \
              -H "Reflections-Version: 2026-10-15" \
              -H "Idempotency-Key: $REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "receipt": "rcpt_hk5zba2q8v1m3n7p4r6s9t0wxy"
            }'
        - lang: typescript
          label: TypeScript
          source: >
            import { env, exit } from "node:process";


            // Set a unique key once per new action; persist it and reuse it for
            every retry.

            const apiKey = env.REFLECTIONS_KEY;

            if (!apiKey) throw new Error("Set REFLECTIONS_KEY before running
            this example");

            const idempotencyKey =
            env.REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY;

            if (!idempotencyKey) throw new Error("Set
            REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY before running this
            example");


            const response = await
            fetch("https://app.reflections.ai/v1/verifications", {
              method: "POST",
              headers: {
                Authorization: `Bearer ${apiKey}`,
                "Reflections-Version": "2026-10-15",
                "Idempotency-Key": idempotencyKey,
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                "receipt": "rcpt_hk5zba2q8v1m3n7p4r6s9t0wxy"
              }),
              signal: AbortSignal.timeout(30_000),
            });

            const responseBody = await response.text();

            if (!response.ok) {
              console.error(`HTTP ${response.status}: ${responseBody}`);
              exit(1);
            }

            console.log(responseBody);
        - lang: python
          label: Python
          source: >
            import json

            import os

            from urllib.error import HTTPError

            from urllib.request import Request, urlopen


            # Set a unique key once per new action; persist it and reuse it for
            every retry.

            apiKey = os.environ["REFLECTIONS_KEY"]

            if not apiKey:
                raise ValueError("Set REFLECTIONS_KEY before running this example")
            idempotencyKey =
            os.environ["REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY"]

            if not idempotencyKey:
                raise ValueError("Set REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY before running this example")

            headers = {
                "Authorization": f"Bearer {apiKey}",
                "Reflections-Version": "2026-10-15",
                "Idempotency-Key": idempotencyKey,
                "Content-Type": "application/json",
            }

            data = json.dumps({"receipt":
            "rcpt_hk5zba2q8v1m3n7p4r6s9t0wxy"}).encode("utf-8")

            request = Request("https://app.reflections.ai/v1/verifications",
                              method="POST", headers=headers, data=data)
            try:
                with urlopen(request, timeout=30) as response:
                    print(response.read().decode("utf-8"))
            except HTTPError as error:
                error_body = error.read().decode("utf-8")
                raise RuntimeError(f"HTTP {error.code}: {error_body}") from error
        - lang: go
          label: Go
          source: |
            package main

            import (
                "fmt"
                "io"
                "net/http"
                "os"
                "strings"
                "time"
            )

            func main() {
                // Set a unique key once per new action; persist it and reuse it for every retry.
                apiKey := os.Getenv("REFLECTIONS_KEY")
                if apiKey == "" {
                    panic("Set REFLECTIONS_KEY before running this example")
                }
                idempotencyKey := os.Getenv("REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY")
                if idempotencyKey == "" {
                    panic("Set REFLECTIONS_CREATE_VERIFICATION_IDEMPOTENCY_KEY before running this example")
                }

                body := strings.NewReader(`{
                  "receipt": "rcpt_hk5zba2q8v1m3n7p4r6s9t0wxy"
                }`)
                request, err := http.NewRequest("POST", "https://app.reflections.ai/v1/verifications", body)
                if err != nil {
                    panic(err)
                }
                request.Header.Set("Authorization", "Bearer " + apiKey)
                request.Header.Set("Reflections-Version", "2026-10-15")
                request.Header.Set("Idempotency-Key", idempotencyKey)
                request.Header.Set("Content-Type", "application/json")
                client := &http.Client{Timeout: 30 * time.Second}
                response, err := client.Do(request)
                if err != nil {
                    panic(err)
                }
                defer response.Body.Close()
                responseBody, err := io.ReadAll(response.Body)
                if err != nil {
                    panic(err)
                }
                if response.StatusCode < 200 || response.StatusCode >= 300 {
                    panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, responseBody))
                }
                fmt.Print(string(responseBody))
            }
components:
  parameters:
    ReflectionsVersion:
      name: Reflections-Version
      in: header
      required: false
      description: >-
        The dated API version. Defaults to the version your account is pinned
        to.
      schema:
        type: string
        example: '2026-10-15'
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >
        A unique key for this operation, up to 255 characters. In test mode,
        POST keys are scoped

        to your account and mode and bind the endpoint and body for 24 hours. A
        different endpoint

        or body with the same key is refused.


        Initial live check and generation creation require a nonempty key. Each
        operation has a

        separate account-scoped namespace; retain the same API key, body and
        idempotency key for

        retries within 24 hours of creation. A pending check returns `202` with
        `status: "checking"`.

        Completed checks replay their sealed response; successful generation
        POSTs replay the

        original accepted `202`, so use GET for current state. Live verification
        is a read-only

        query that returns a fresh verification ID on each call, without exact
        response caching.


        The broader delegated-account contract also scopes keys to
        `Reflections-Account`;

        delegated requests and the other planned live POST operations remain
        unsupported.
      schema:
        type: string
        maxLength: 255
  schemas:
    VerificationCreate:
      type: object
      description: >-
        Send exactly one of `receipt`, `manifest`, `url`, `sha256` or
        `fingerprint`.
      properties:
        receipt:
          type: string
          description: A receipt ID or JWS.
        manifest:
          type: string
          contentEncoding: base64
          description: A C2PA manifest store.
        url:
          type: string
          format: uri
          description: A file Reflections can fetch.
        sha256:
          $ref: '#/components/schemas/Sha256Hex'
          description: >
            SHA-256 of the file's bytes, in hex. Matches only an exact copy of a
            registered output.
        fingerprint:
          $ref: '#/components/schemas/Fingerprint'
          description: >-
            A fingerprint you computed, when the bytes cannot leave your
            platform.
    Verification:
      type: object
      required:
        - id
        - object
        - result
        - method
        - created_at
      properties:
        id:
          type: string
          pattern: ^vrf_[0-9a-hjkmnp-tv-z]{26}$
          description: Unique identifier, prefixed `vrf_`.
        object:
          type: string
          const: verification
          description: Always `verification`.
        result:
          type: string
          enum:
            - verified
            - not_found
            - invalid
          description: >-
            `verified`: a valid receipt matches. `not_found`: nothing matches;
            this says nothing about whether the content is licensed. `invalid`:
            a receipt or manifest is present and fails verification.
        method:
          type: string
          enum:
            - receipt
            - manifest
            - digest
            - fingerprint
            - watermark
          description: >
            How the content matched: its `receipt`, an embedded `manifest`, the
            exact `digest`, a

            `fingerprint` or a `watermark`.
        match:
          type:
            - object
            - 'null'
          description: >-
            How the file matched a registered output, for `digest`,
            `fingerprint` and `watermark`. `null` when a receipt or manifest
            matched.
          properties:
            exact:
              type: boolean
              description: The bytes match the registered digest.
            confidence:
              type: string
              enum:
                - exact
                - high
                - medium
              description: >
                How close the match is: `exact` for the registered bytes, `high`
                or `medium` for a

                fingerprint. Treat `medium` as weaker evidence.
        manifest:
          type:
            - object
            - 'null'
          description: >
            The C2PA manifest read from the file or sent as `manifest`. `null`
            when none was read.
          properties:
            signer:
              type: string
              description: The C2PA claim signer.
            assertion_present:
              type: boolean
              description: >-
                Whether the manifest carries the `ai.reflections.license`
                assertion.
            signature_valid:
              type: boolean
              description: >
                Whether the C2PA claim signature verifies. The receipt inside is
                checked separately,

                against Reflections' keys.
        receipt:
          description: >
            The matching receipt, in full, with its live `use_status`. `null`
            when nothing matched.
          oneOf:
            - $ref: '#/components/schemas/Receipt'
            - type: 'null'
        detail:
          type:
            - string
            - 'null'
          description: What failed, when `result` is `invalid`. Otherwise `null`.
        created_at:
          type: string
          format: date-time
          description: When the verification was made.
    Sha256Hex:
      type: string
      description: A SHA-256 digest of bytes, as 64 lowercase hex characters.
      pattern: ^[0-9a-f]{64}$
    Fingerprint:
      type: object
      description: >
        A fingerprint of a file, for verification when you cannot send the file
        itself. It matches

        the file to a registered output; it supports no rule checks.
      properties:
        perceptual_hash:
          type: object
          description: A perceptual hash of the file.
          required:
            - algorithm
            - value
          properties:
            algorithm:
              type: string
              enum:
                - pdq
                - vpdq
                - chromaprint
              description: '`pdq` for images, `vpdq` for video, `chromaprint` for audio.'
            value:
              type: string
              description: >
                The hash in the algorithm's standard text form, such as 64 hex
                characters for `pdq`.
        embeddings:
          type: array
          items:
            type: object
            required:
              - model
              - vector
            properties:
              model:
                type: string
                enum:
                  - reflections-face-1
                  - reflections-voice-1
                description: >
                  The model that computed `vector`: `reflections-face-1` for
                  faces,

                  `reflections-voice-1` for voices.
              vector:
                type: string
                contentEncoding: base64
                description: Little-endian float32 values.
          description: >
            Optional face or voice embeddings of the file, used with the hash to
            look it up.
    Receipt:
      type: object
      required:
        - id
        - object
        - livemode
        - kind
        - subject
        - decision
        - assurance
        - talent
        - licenses
        - jws
        - use_status
        - issued_at
      properties:
        id:
          type: string
          pattern: ^rcpt_[0-9a-hjkmnp-tv-z]{26}$
          description: Unique identifier, prefixed `rcpt_`. The JWS carries it as `jti`.
        object:
          type: string
          const: receipt
          description: Always `receipt`.
        livemode:
          type: boolean
          description: >
            `false` for a test-mode receipt, signed with a test key. It verifies
            only with a test

            key.
        kind:
          type: string
          enum:
            - check
            - generation
          description: Whether `subject` is a check or a generation.
        subject:
          type: string
          description: The check or generation ID.
        decision:
          type: string
          enum:
            - allow
            - deny
          description: >-
            A receipt records a final decision. An escalated check or output
            gets its receipt when it is decided.
        assurance:
          type: string
          enum:
            - observed
            - attested
          description: >
            `observed`: Reflections checked these bytes or this request itself.
            `attested`:

            Reflections recorded what the platform stated, such as text sent
            `withheld`.
        talent:
          type: array
          description: Every talent the decision covers.
          items:
            type: string
            pattern: ^tal_[0-9a-hjkmnp-tv-z]{26}$
        licenses:
          type: array
          description: >
            The signed terms the decision relied on, one entry per talent whose
            license applied, in

            the order of `talent`. Empty when no license applied, as for a check
            whose inputs

            invoke no talent, or a `deny` with `no_license`.
          items:
            $ref: '#/components/schemas/ReceiptLicense'
        licensee:
          type:
            - string
            - 'null'
          pattern: ^acct_[0-9a-hjkmnp-tv-z]{26}$
          description: The account whose license applied. `null` when no license applied.
        platform:
          type: string
          pattern: ^acct_[0-9a-hjkmnp-tv-z]{26}$
          description: The platform that made the request.
        request_digest:
          allOf:
            - $ref: '#/components/schemas/Digest'
          description: >-
            The request digest of the check, or for a generation, of the check
            it was made under.
        artifact_sha256:
          description: >
            SHA-256, in hex, of the bytes submitted to the generation, before
            any C2PA manifest was

            embedded. `null` on a check receipt.
          oneOf:
            - $ref: '#/components/schemas/Sha256Hex'
            - type: 'null'
        permitted_use:
          type:
            - object
            - 'null'
          description: The use the receipt covers.
          properties:
            modality:
              $ref: '#/components/schemas/Modality'
              description: What was generated.
            purpose:
              $ref: '#/components/schemas/Purpose'
              description: The purpose the use covers.
            channels:
              type: array
              items:
                $ref: '#/components/schemas/Channel'
              description: Where the output may appear.
            territories:
              type: array
              items:
                $ref: '#/components/schemas/Territory'
              description: >-
                Where the output may be shown, as country codes or `WW` for
                worldwide.
            ends_at:
              type:
                - string
                - 'null'
              format: date-time
              description: >
                When the use window ends; `use_status` then becomes `expired`.
                `null` when the use

                has no end date.
        obligations:
          type: array
          items:
            $ref: '#/components/schemas/Obligation'
          description: The obligations the decision carried, with all their fields.
        c2pa_signer:
          $ref: '#/components/schemas/C2paSigner'
          description: >
            Generations only, when the platform declared it: the C2PA claim
            signer the receipt is

            bound to, signed as `tlp.c2pa_signer`. Absent means unbound: the
            receipt proves the

            decision, not which file carries it.
        use_status:
          oneOf:
            - $ref: '#/components/schemas/UseStatus'
            - type: 'null'
          description: >-
            Whether the output may still be used. `null` on a `deny` receipt,
            which permits nothing.
        use_status_changed_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When `use_status` last changed. `null` if it never has.
        jws:
          type: string
          description: The signed receipt, a compact JWS with `typ` `tlp-receipt+jwt`.
        cose:
          type: string
          contentEncoding: base64
          description: >-
            The same claims as a tagged COSE_Sign1 structure, for tools that
            work in CBOR.
        page_url:
          type: string
          format: uri
          description: The public receipt page.
        issued_at:
          type: string
          format: date-time
          description: >
            When the decision was made and the receipt signed. The JWS carries
            it as `iat`.
    Problem:
      type: object
      description: An RFC 9457 problem detail. Every error has this shape.
      required:
        - type
        - title
        - status
        - code
        - request_id
      properties:
        type:
          type: string
          format: uri
          description: A URL for this error, under `https://docs.reflections.ai/errors/`.
        title:
          type: string
          description: A short summary of the error.
        status:
          type: integer
          description: The HTTP status.
        detail:
          type: string
          description: What happened in this request.
        code:
          $ref: '#/components/schemas/ErrorCode'
          description: The stable error code. Branch on it, then on `status`.
        param:
          type: string
          description: The field at fault, as a path such as `use.territories[1]`.
        request_id:
          type: string
          description: >
            `req_…`, the same value as the `Request-Id` header. Include it when
            you contact support.
        doc_url:
          type: string
          format: uri
          description: A link to the documentation for this error.
    ReceiptLicense:
      type: object
      required:
        - talent
        - license
        - license_revision
        - terms_digest
      properties:
        talent:
          type: string
          pattern: ^tal_[0-9a-hjkmnp-tv-z]{26}$
          description: The talent whose license applied.
        license:
          type: string
          pattern: ^lic_[0-9a-hjkmnp-tv-z]{26}$
          description: The license the decision relied on.
        license_revision:
          type: string
          pattern: ^lrv_[0-9a-hjkmnp-tv-z]{26}$
          description: >
            The signed revision of that license the decision relied on. The JWS
            claim names it

            `revision`.
        terms_digest:
          $ref: '#/components/schemas/Digest'
          description: >
            The `terms_digest` of that revision. Compare it with the revision's
            own to confirm which

            terms applied.
    Digest:
      type: string
      description: A SHA-256 digest, `sha256:` followed by 64 lowercase hex characters.
      pattern: ^sha256:[0-9a-f]{64}$
    Modality:
      type: string
      description: >-
        What will be generated. `speech` is a voice speaking words; `audio` is
        any other sound.
      enum:
        - image
        - video
        - speech
        - audio
        - text
    Purpose:
      type: string
      enum:
        - advertising
        - branded_content
        - entertainment
        - editorial
        - personal
        - education
        - political
    Channel:
      type: string
      description: Where the output will appear.
      enum:
        - social
        - web
        - in_app
        - streaming
        - tv
        - cinema
        - out_of_home
        - print
        - audio
        - email
        - retail
        - games
        - private
    Territory:
      type: string
      description: An ISO 3166-1 alpha-2 country code, or `WW` for worldwide.
      pattern: ^([A-Z]{2})$
      example: US
    Obligation:
      type: object
      description: >-
        Something you must do to proceed. Each type uses only the fields listed
        for it.
      required:
        - type
      properties:
        type:
          $ref: '#/components/schemas/ObligationType'
          description: >
            The kind of obligation. Treat a type you do not know as unmet: do
            not generate or

            deliver.
        required:
          type: string
          enum:
            - all
            - sampled
          description: >-
            `generation_check`: submit every output, or the sampled share in
            `sample_rate`.
        sample_rate:
          type: number
          minimum: 0
          maximum: 1
          description: >
            `generation_check` with `required: sampled`: the share of outputs to
            submit, from 0 to

            1, chosen at random.
        reviewer:
          type: string
          enum:
            - talent
            - representative
            - reflections
          description: '`hold_until_release`: who releases each output.'
        instructions:
          type: array
          items:
            type: string
          description: '`generation_instructions`: include these in what the model receives.'
        level:
          type: string
          enum:
            - licensed
            - brand
            - scope
          description: >-
            `disclosure`: `licensed` says the person's likeness is licensed;
            `brand` adds who licensed it; `scope` adds the use.
        text:
          type: string
          description: '`disclosure` and `attribution`: the words to show.'
        placement:
          type: string
          enum:
            - visible
            - metadata
            - both
          description: '`disclosure`: where the label goes.'
        material:
          type: string
          enum:
            - references
            - voice
            - outputs
          description: '`delete_material` and `no_training`: what the obligation covers.'
        within:
          allOf:
            - $ref: '#/components/schemas/Duration'
          description: >-
            The deadline. `delete_material`: counted from the decision.
            `usage_report`: from the generation's decision or the session's end.
        units:
          type: string
          enum:
            - outputs
            - seconds
            - characters
            - placements
            - impressions
          description: '`usage_report`: the unit to report.'
        term:
          $ref: '#/components/schemas/Address'
          description: The address of the license term the obligation comes from.
    C2paSigner:
      type: object
      required:
        - thumbprint
      additionalProperties: false
      properties:
        thumbprint:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
          description: >
            `sha256:` and the lowercase hex SHA-256 of the DER encoding of the
            certificate that

            signs the C2PA claim, the end-entity certificate in the manifest's
            signature.
    UseStatus:
      type: string
      description: >
        What use of the output is permitted now. `permitted`: within the
        receipt's scope.

        `ceased`: no new placements, after a revocation. `withdrawn`: take it
        down. `expired`:

        the use window ended.
      enum:
        - permitted
        - ceased
        - withdrawn
        - expired
    ErrorCode:
      type: string
      description: A stable error code. See the error code catalog.
      enum:
        - invalid_request
        - parameter_missing
        - parameter_invalid
        - unsupported_modality
        - unsupported_media_type
        - media_unreadable
        - version_unsupported
        - authorization_code_invalid
        - authentication_required
        - invalid_api_key
        - token_invalid
        - insufficient_scope
        - account_not_connected
        - mandate_required
        - livemode_mismatch
        - live_not_activated
        - platform_not_permitted
        - resource_not_found
        - idempotency_key_in_use
        - generation_already_submitted
        - authorization_consumed
        - check_not_allowed
        - check_expired
        - escalation_closed
        - license_draft_closed
        - invalid_state_transition
        - session_not_active
        - payload_too_large
        - idempotency_key_reused
        - artifact_digest_mismatch
        - rate_limited
        - internal_error
        - service_unavailable
        - evaluation_timeout
    ObligationType:
      type: string
      description: >
        `generation_check`: submit outputs before delivery.
        `hold_until_release`: deliver nothing

        until the reviewer releases it. `draft_watermark`: mark drafts shown
        while held.

        `generation_instructions`: pass the instructions to the model.
        `disclosure`,

        `attribution`: label the output as stated. `c2pa_manifest`: embed the
        `c2pa` assertion.

        `no_training`: never train on the material. `delete_material`: delete it
        within `within`.

        `usage_report`: report usage within `within`.
      enum:
        - generation_check
        - hold_until_release
        - draft_watermark
        - generation_instructions
        - disclosure
        - attribution
        - c2pa_manifest
        - no_training
        - delete_material
        - usage_report
    Duration:
      type: string
      description: An ISO 8601 duration, such as `PT60S` or `P30D`.
      example: P30D
    Address:
      type: string
      description: >
        Where a reason or finding rests, written as an address:
        `license:<id>/terms.<key>` for a

        term, `talent:<id>` for a talent's standing boundary.
      example: license:lic_k5zba2q8v1m3n7p4r6s9t0wxyh/terms.channels
  headers:
    RequestId:
      description: Identifies this request. Include it when you contact support.
      schema:
        type: string
        example: req_8f2k4m6p8r0t2v4x6z8b0d2f4h
    RateLimit:
      description: >-
        Remaining quota and seconds until it resets, as IETF RateLimit header
        fields.
      schema:
        type: string
        example: '"checks";r=184;t=1'
    RateLimitPolicy:
      description: The policy the RateLimit field reports against.
      schema:
        type: string
        example: '"checks";q=200;w=1'
    RetryAfter:
      description: Seconds to wait before retrying.
      schema:
        type: integer
  examples:
    Verification:
      summary: A file matched by its manifest
      value:
        id: vrf_8b0c2d4e6f8g0h2j4k6m8n0p2q
        object: verification
        result: verified
        method: manifest
        match: null
        manifest:
          signer: Northlight
          assertion_present: true
          signature_valid: true
        receipt:
          id: rcpt_hk5zba2q8v1m3n7p4r6s9t0wxy
          object: receipt
          livemode: true
          kind: generation
          subject: gen_2q8v1m3n7p4r6s9t0wxyhk5zba
          decision: allow
          assurance: observed
          talent:
            - tal_9t0wxyhk5zba2q8v1m3n7p4r6s
          licenses:
            - talent: tal_9t0wxyhk5zba2q8v1m3n7p4r6s
              license: lic_ba2q8v1m3n7p4r6s9t0wxyhk5z
              license_revision: lrv_7p4r6s9t0wxyhk5zba2q8v1m3n
              terms_digest: >-
                sha256:8e0a2c4e6b8d0f2a4c6e8b0d2f4a6c8e0b2d4f6a8c0e2b4d6f8a0c2e4b6d8f0a
          request_digest: >-
            sha256:d4f6b8a0c2e4d6f8b0a2c4e6d8f0b2a4c6e8d0f2b4a6c8e0d2f4b6a8c0e2d4f6
          jws: eyJhbGciOiJFUzI1NiIs…
          use_status: permitted
          issued_at: '2026-10-17T18:06:03Z'
        detail: null
        created_at: '2026-10-18T09:12:44Z'
  responses:
    BadRequest:
      description: The request was malformed or a parameter was invalid.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.reflections.ai/errors/parameter_invalid
            title: A parameter is invalid
            status: 400
            code: parameter_invalid
            param: use.territories[1]
            detail: '"UK" is not an ISO 3166-1 alpha-2 code. Use "GB".'
            request_id: req_8f2k4m6p8r0t2v4x6z8b0d2f4h
    Unauthorized:
      description: The key is missing, unknown or revoked.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.reflections.ai/errors/invalid_api_key
            title: The API key is not valid
            status: 401
            code: invalid_api_key
            request_id: req_8f2k4m6p8r0t2v4x6z8b0d2f4h
    Conflict:
      description: >-
        The request conflicts with the object's state or with a request still
        running.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.reflections.ai/errors/idempotency_key_in_use
            title: A request with this key is still running
            status: 409
            code: idempotency_key_in_use
            detail: Retry with the same key after a short wait.
            request_id: req_8f2k4m6p8r0t2v4x6z8b0d2f4h
    PayloadTooLarge:
      description: >-
        The request exceeds its byte limit. Sandbox inline media is at most 7
        MiB decoded and the generation JSON body at most 10 MiB. Multipart
        uploads are planned.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unprocessable:
      description: The request is well formed but cannot be applied.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.reflections.ai/errors/idempotency_key_reused
            title: This key was used for a different request
            status: 422
            code: idempotency_key_reused
            request_id: req_8f2k4m6p8r0t2v4x6z8b0d2f4h
    RateLimited:
      description: Too many requests.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.reflections.ai/errors/rate_limited
            title: Too many requests
            status: 429
            code: rate_limited
            request_id: req_8f2k4m6p8r0t2v4x6z8b0d2f4h
    ServerError:
      description: Something failed on our side. Retry with the same idempotency key.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unavailable:
      description: >
        Reflections is temporarily unavailable. Do not generate a named talent
        without a valid

        authorization. Retry with the same idempotency key.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Timeout:
      description: >-
        Verification did not finish in time. Retry, or verify by receipt instead
        of by file.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  securitySchemes:
    SecretKey:
      type: http
      scheme: bearer
      description: >
        Your secret key, `rk_test_…` or `rk_live_…`, sent as `Authorization:
        Bearer <key>`. Keep it

        on your server. Restricted keys carry only the scopes you give them.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.