> ## 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.

# Create a check

> **Test mode available. Live mode available when configured.** This describes source support;
production activation is not established. Until activation, a live key receives `403`
[`live_not_activated`](/api-reference/errors#live_not_activated); do not retry it. Sandbox
checks evaluate fictional fixtures and text inputs; see [Sandbox](/sandbox).

The initial live implementation requires one explicit owned `license`, text inputs totaling
at most 64 KiB, image depiction for commercial advertising or branded content, one candidate,
and `on_escalate: "deny"`. Every channel and territory must match the signed scope; only
signed `WW` means worldwide. Declare `execution.provider` and `execution.model` for the
later output. `job_id` is optional. Reference media, talent/facet selection, end users,
reuse and nondefault prompt handling are unsupported.

The license must newly sign `externalCreation: "images.v1"` and
`externalCreationPostRevocation: "retain"`. Live signing requires protected activation after
the public key's 30-day publication period. Send an `Idempotency-Key`. While evaluation is
pending, the response is `202` with `status: "checking"`, `decision: null` and
`Retry-After`; retry with the same body and key. Retries never start another paid
evaluation. See [the initial live image journey](/guides/image-and-video-platforms#initial-live-image-implementation).

**Broader protocol contract:** the remaining description and examples include planned
forms beyond that initial live implementation.

Decides whether a use of a talent may proceed, before you generate anything. Send the
request your model will actually receive: the user's prompt, any system text you add, your
rewritten prompt, and every reference.

The response always has a `decision`:

- `allow`: generate, and meet every obligation, including `generation_check`.
- `deny`: do not generate. `reasons` say why in the license's own words; `remedy` says what
  would change the answer.
- `escalate`: do not generate yet. A person with authority will decide. Listen for
  `check.resolved` or poll this check. An unanswered escalation becomes `deny` at
  `escalation.expires_at`.

Reflections resolves the inputs of every check. Talent named in `talent` are matched as
`explicit`, and anyone else the inputs name or show is added. If no protected talent is
found, the decision is `allow` with `talent: []` and no obligations. Reflections checks only the talent
the check resolves; it does not screen outputs for talent nobody named.

Restricted keys need `checks:write`.




## OpenAPI

````yaml /api-reference/openapi.yaml post /checks
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:
  /checks:
    post:
      tags:
        - Checks
      summary: Create a check
      description: >
        **Test mode available. Live mode available when configured.** This
        describes source support;

        production activation is not established. Until activation, a live key
        receives `403`

        [`live_not_activated`](/api-reference/errors#live_not_activated); do not
        retry it. Sandbox

        checks evaluate fictional fixtures and text inputs; see
        [Sandbox](/sandbox).


        The initial live implementation requires one explicit owned `license`,
        text inputs totaling

        at most 64 KiB, image depiction for commercial advertising or branded
        content, one candidate,

        and `on_escalate: "deny"`. Every channel and territory must match the
        signed scope; only

        signed `WW` means worldwide. Declare `execution.provider` and
        `execution.model` for the

        later output. `job_id` is optional. Reference media, talent/facet
        selection, end users,

        reuse and nondefault prompt handling are unsupported.


        The license must newly sign `externalCreation: "images.v1"` and

        `externalCreationPostRevocation: "retain"`. Live signing requires
        protected activation after

        the public key's 30-day publication period. Send an `Idempotency-Key`.
        While evaluation is

        pending, the response is `202` with `status: "checking"`, `decision:
        null` and

        `Retry-After`; retry with the same body and key. Retries never start
        another paid

        evaluation. See [the initial live image
        journey](/guides/image-and-video-platforms#initial-live-image-implementation).


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

        forms beyond that initial live implementation.


        Decides whether a use of a talent may proceed, before you generate
        anything. Send the

        request your model will actually receive: the user's prompt, any system
        text you add, your

        rewritten prompt, and every reference.


        The response always has a `decision`:


        - `allow`: generate, and meet every obligation, including
        `generation_check`.

        - `deny`: do not generate. `reasons` say why in the license's own words;
        `remedy` says what
          would change the answer.
        - `escalate`: do not generate yet. A person with authority will decide.
        Listen for
          `check.resolved` or poll this check. An unanswered escalation becomes `deny` at
          `escalation.expires_at`.

        Reflections resolves the inputs of every check. Talent named in `talent`
        are matched as

        `explicit`, and anyone else the inputs name or show is added. If no
        protected talent is

        found, the decision is `allow` with `talent: []` and no obligations.
        Reflections checks only the talent

        the check resolves; it does not screen outputs for talent nobody named.


        Restricted keys need `checks:write`.
      operationId: createCheck
      parameters:
        - $ref: '#/components/parameters/ReflectionsVersion'
        - $ref: '#/components/parameters/ReflectionsAccount'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckCreate'
            examples:
              sandbox_image:
                summary: Supported sandbox request (replace object IDs with your own)
                value:
                  inputs:
                    - role: prompt
                      text: Maya Okafor running a mountain trail at sunrise
                  use:
                    modality: image
                    kind: depiction
                    purpose: advertising
                    commercial: true
                    channels:
                      - social
                    territories:
                      - US
                  execution:
                    provider: sandbox-fixture
                    model: one-pixel-png
                    candidates: 1
              image_ad:
                summary: An image for an ad
                value:
                  inputs:
                    - role: prompt
                      text: >-
                        Maya Okafor holding our new trail shoe on a rocky ridge
                        at sunrise
                    - role: rewritten_prompt
                      text: >-
                        Photoreal portrait of Maya Okafor, golden-hour light,
                        holding a grey trail running shoe, rocky ridge, wide
                        shot
                    - role: reference
                      file: file_7h3k9m2p4q6r8s1t3v5w7x9yza
                  use:
                    modality: image
                    kind: depiction
                    purpose: advertising
                    commercial: true
                    channels:
                      - social
                      - web
                    territories:
                      - US
                      - CA
                  end_user:
                    id: usr_48213
                  execution:
                    provider: example-image-provider
                    model: image-model-3
                    candidates: 4
                  on_escalate: hold
              voice_line:
                summary: A speech line in a licensed voice
                value:
                  talent:
                    - tal_9t0wxyhk5zba2q8v1m3n7p4r6s
                  inputs:
                    - role: script
                      text: Welcome back to the Ridge Runners podcast.
                  use:
                    modality: speech
                    kind: impersonation
                    purpose: branded_content
                    commercial: true
                    channels:
                      - audio
                      - web
                    territories:
                      - US
                  execution:
                    provider: example-voice-provider
                    model: tts-2
                    candidates: 1
                  on_escalate: deny
      responses:
        '200':
          description: The check, with its decision.
          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/Check'
              examples:
                allow:
                  $ref: '#/components/examples/CheckAllow'
                deny:
                  $ref: '#/components/examples/CheckDeny'
                escalate:
                  $ref: '#/components/examples/CheckEscalate'
        '202':
          description: >
            Live mode: evaluation has not finished. The check has `status:
            "checking"` and no

            decision, authorization or receipt. Retry the same body and key
            after `Retry-After`.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimitPolicy'
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Check'
              examples:
                checking:
                  $ref: '#/components/examples/CheckChecking'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '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'
      security:
        - SecretKey:
            - checks:write
      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_CHECK_IDEMPOTENCY_KEY:?Set
            REFLECTIONS_CREATE_CHECK_IDEMPOTENCY_KEY before running this
            example}"


            curl --fail-with-body --max-time 30 -X POST
            'https://app.reflections.ai/v1/checks' \
              -H "Authorization: Bearer $REFLECTIONS_KEY" \
              -H "Reflections-Version: 2026-10-15" \
              -H "Idempotency-Key: $REFLECTIONS_CREATE_CHECK_IDEMPOTENCY_KEY" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "inputs": [
                {
                  "role": "prompt",
                  "text": "Maya Okafor running a mountain trail at sunrise"
                }
              ],
              "use": {
                "modality": "image",
                "kind": "depiction",
                "purpose": "advertising",
                "commercial": true,
                "channels": [
                  "social"
                ],
                "territories": [
                  "US"
                ]
              },
              "execution": {
                "provider": "sandbox-fixture",
                "model": "one-pixel-png",
                "candidates": 1
              }
            }'
        - 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_CHECK_IDEMPOTENCY_KEY;

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


            const response = await fetch("https://app.reflections.ai/v1/checks",
            {
              method: "POST",
              headers: {
                Authorization: `Bearer ${apiKey}`,
                "Reflections-Version": "2026-10-15",
                "Idempotency-Key": idempotencyKey,
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                "inputs": [
                  {
                    "role": "prompt",
                    "text": "Maya Okafor running a mountain trail at sunrise"
                  }
                ],
                "use": {
                  "modality": "image",
                  "kind": "depiction",
                  "purpose": "advertising",
                  "commercial": true,
                  "channels": [
                    "social"
                  ],
                  "territories": [
                    "US"
                  ]
                },
                "execution": {
                  "provider": "sandbox-fixture",
                  "model": "one-pixel-png",
                  "candidates": 1
                }
              }),
              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_CHECK_IDEMPOTENCY_KEY"]

            if not idempotencyKey:
                raise ValueError("Set REFLECTIONS_CREATE_CHECK_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({
                "inputs": [{"role": "prompt", "text": "Maya Okafor running a mountain trail at sunrise"}],
                "use": {
                    "modality": "image",
                    "kind": "depiction",
                    "purpose": "advertising",
                    "commercial": True,
                    "channels": ["social"],
                    "territories": ["US"],
                },
                "execution": {"provider": "sandbox-fixture", "model": "one-pixel-png", "candidates": 1},
            }).encode("utf-8")

            request = Request("https://app.reflections.ai/v1/checks",
                              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_CHECK_IDEMPOTENCY_KEY")
                if idempotencyKey == "" {
                    panic("Set REFLECTIONS_CREATE_CHECK_IDEMPOTENCY_KEY before running this example")
                }

                body := strings.NewReader(`{
                  "inputs": [
                    {
                      "role": "prompt",
                      "text": "Maya Okafor running a mountain trail at sunrise"
                    }
                  ],
                  "use": {
                    "modality": "image",
                    "kind": "depiction",
                    "purpose": "advertising",
                    "commercial": true,
                    "channels": [
                      "social"
                    ],
                    "territories": [
                      "US"
                    ]
                  },
                  "execution": {
                    "provider": "sandbox-fixture",
                    "model": "one-pixel-png",
                    "candidates": 1
                  }
                }`)
                request, err := http.NewRequest("POST", "https://app.reflections.ai/v1/checks", 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'
    ReflectionsAccount:
      name: Reflections-Account
      in: header
      required: false
      description: >
        Act for a connected licensee. The value is the licensee's account ID.
        Requires an active

        connection between that account and yours.
      schema:
        type: string
        pattern: ^acct_[0-9a-hjkmnp-tv-z]{26}$
    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:
    CheckCreate:
      type: object
      required:
        - inputs
        - use
      properties:
        talent:
          type: array
          description: >-
            Talent your user picked. The inputs are still resolved for anyone
            else.
          items:
            type: string
            pattern: ^tal_[0-9a-hjkmnp-tv-z]{26}$
          maxItems: 10
        exclude_talent:
          type: array
          description: Talent your user confirmed they did not mean.
          items:
            type: string
            pattern: ^tal_[0-9a-hjkmnp-tv-z]{26}$
        facet:
          type: string
          pattern: ^fct_[0-9a-hjkmnp-tv-z]{26}$
          description: A specific facet, such as one of several voices.
        license:
          type: string
          pattern: ^lic_[0-9a-hjkmnp-tv-z]{26}$
          description: >-
            Use this license. By default the narrowest license that allows the
            use is chosen.
        inputs:
          type: array
          minItems: 1
          maxItems: 64
          items:
            $ref: '#/components/schemas/Input'
          description: >
            Everything the model will receive, in order: the user's prompt, your
            system text, any

            rewritten prompt, references and conversation history.
        use:
          $ref: '#/components/schemas/Use'
          description: How the output will be used. A different use needs a new check.
        end_user:
          $ref: '#/components/schemas/EndUser'
          description: >-
            The person the request is for. Send it on every check made for a
            person.
        execution:
          $ref: '#/components/schemas/Execution'
          description: >
            The model that will run the request and how many outputs it will
            make. `provider` and

            `model` are part of `request_digest`.
        on_escalate:
          type: string
          enum:
            - hold
            - deny
          default: hold
          description: >-
            `deny`: never escalate; return `deny` with `review_required`
            instead. Use it for interactive products.
        reuse:
          type: object
          description: >
            Let one decision cover several generations of the same use, talent,
            execution and end

            user until `max_generations` or `ttl` runs out, even when later
            inputs differ. Each

            generation is still checked on its output. Generations under `reuse`
            omit

            `candidate_index`.
          properties:
            max_generations:
              type: integer
              minimum: 1
              maximum: 1000
              description: Generations the window covers, up to 1,000.
            ttl:
              allOf:
                - $ref: '#/components/schemas/Duration'
              description: How long the window lasts. At most `PT15M`.
        prompt_handling:
          $ref: '#/components/schemas/PromptHandling'
          description: >
            How text inputs reach Reflections: `full` by default, `redacted` or
            `withheld`.
        metadata:
          $ref: '#/components/schemas/Metadata'
          description: Your own keys, returned on the check.
    Check:
      type: object
      required:
        - id
        - object
        - livemode
        - status
        - decision
        - talent
        - use
        - reasons
        - obligations
        - request_digest
        - created_at
      properties:
        id:
          type: string
          pattern: ^chk_[0-9a-hjkmnp-tv-z]{26}$
          description: The check's ID, `chk_` followed by 26 characters.
        object:
          type: string
          const: check
          description: Always `check`.
        livemode:
          type: boolean
          description: '`true` in live mode, `false` in test mode.'
        status:
          $ref: '#/components/schemas/CheckStatus'
          description: >
            Where the check is now. An `allow` can later become `consumed`,
            `expired` or

            `cancelled`; an `escalate` ends `allowed`, `denied` or `cancelled`.
        decision:
          description: >
            `allow`, `deny` or `escalate`. An escalated check's decision becomes
            `allow` or `deny`

            when a person decides or the escalation expires. Null while `status`
            is `checking`.
          oneOf:
            - $ref: '#/components/schemas/Decision'
            - type: 'null'
        talent:
          type: array
          items:
            $ref: '#/components/schemas/CheckTalent'
          description: >
            Each protected talent the request invokes, with that talent's own
            decision and license.

            Empty when none is found.
        use:
          $ref: '#/components/schemas/Use'
          description: The use the check decided, as you sent it.
        reasons:
          type: array
          items:
            $ref: '#/components/schemas/Reason'
          description: Why the use was denied or escalated. Empty on `allow`.
        obligations:
          type: array
          items:
            $ref: '#/components/schemas/Obligation'
          description: What you must do to proceed. Empty unless `decision` is `allow`.
        authorization:
          description: >
            Proof of the `allow`. Pass `token` to the tool or provider that
            generates. Null unless

            `decision` is `allow`.
          oneOf:
            - $ref: '#/components/schemas/Authorization'
            - type: 'null'
        escalation:
          description: >
            The escalation, when the check is `escalated` or was decided by a
            person. When several

            talent are escalated, each has their own, named in
            `talent[].escalation`. While the

            check is open, this field shows the open one that expires first, so
            its `expires_at` is

            when the check becomes `deny`. Once decided, it shows the one that
            decided: the first

            `deny` or expiry, or the last `allow`. The others still open are
            then `cancelled`.
          oneOf:
            - $ref: '#/components/schemas/Escalation'
            - type: 'null'
        remedy:
          description: >
            What would change a `deny`. Null for other decisions, and when no
            change can help, as

            with `talent_prohibits`.
          oneOf:
            - $ref: '#/components/schemas/Remedy'
            - type: 'null'
        request_digest:
          allOf:
            - $ref: '#/components/schemas/Digest'
          description: >-
            Digest of the inputs, use and execution this check decided. Without
            `reuse`, the authorization covers only this request; with `reuse`,
            it also covers later generations of the same use, talent, execution
            and end user.
        licensee:
          type: string
          pattern: ^acct_[0-9a-hjkmnp-tv-z]{26}$
          description: >
            The account that holds the license: the licensee named in
            `Reflections-Account`, or your

            own account under a platform license.
        platform:
          type: string
          pattern: ^acct_[0-9a-hjkmnp-tv-z]{26}$
          description: The account that ran the check.
        session:
          type:
            - string
            - 'null'
          pattern: ^ses_[0-9a-hjkmnp-tv-z]{26}$
          description: >
            The session this check started, for a check run by `POST
            /v1/sessions`. Null otherwise.
        receipt:
          type:
            - string
            - 'null'
          pattern: ^rcpt_[0-9a-hjkmnp-tv-z]{26}$
          description: >
            The receipt that records the decision. Null until an escalated check
            is decided.
        metadata:
          $ref: '#/components/schemas/Metadata'
          description: Your metadata from the request.
        created_at:
          type: string
          format: date-time
          description: When the check was created.
    Input:
      type: object
      description: >
        One part of the request a model receives, in order. Send text inline;
        send media as a

        file ID, or as `sha256` with a `url` Reflections can fetch.
      required:
        - role
      properties:
        role:
          type: string
          enum:
            - prompt
            - system
            - negative_prompt
            - rewritten_prompt
            - script
            - reference
            - voice_sample
            - mask
            - context
          description: >
            `prompt`: the user's words. `system`: instructions you add.
            `rewritten_prompt`: your

            expansion of the prompt, if the model receives that instead.
            `script`: words to be

            spoken. `reference`, `voice_sample`, `mask`: media the model
            receives. `context`:

            conversation history the model receives.
        text:
          type: string
          maxLength: 32000
          description: >-
            The text, for every role except `reference`, `voice_sample` and
            `mask`.
        file:
          type: string
          pattern: ^file_[0-9a-hjkmnp-tv-z]{26}$
          description: >
            A file ID from `POST /v1/files`, for a `reference`, `voice_sample`
            or `mask` input.
        url:
          type: string
          format: uri
          description: >
            A URL Reflections can fetch the media from. Send `sha256` and
            `media_type` with it.
        sha256:
          $ref: '#/components/schemas/Sha256Hex'
          description: >
            SHA-256 of the bytes, in hex: of the media at `url`, or of a text
            input's UTF-8 bytes

            when `prompt_handling.mode` is `withheld`.
        media_type:
          type: string
          example: image/png
          description: >
            The MIME type of the media at `url`, or `text/plain` for a withheld
            text input.
    Use:
      type: object
      required:
        - modality
        - kind
        - purpose
        - commercial
      properties:
        modality:
          $ref: '#/components/schemas/Modality'
          description: What will be generated.
        kind:
          $ref: '#/components/schemas/UseKind'
          description: How the talent appears in the output.
        purpose:
          $ref: '#/components/schemas/Purpose'
          description: What the output is for.
        commercial:
          type: boolean
          description: >-
            Whether anyone earns money from the output, including through
            advertising.
        channels:
          type: array
          items:
            $ref: '#/components/schemas/Channel'
          maxItems: 20
          description: Required when `commercial` is true.
        territories:
          type: array
          items:
            $ref: '#/components/schemas/Territory'
          maxItems: 50
          description: Required when `commercial` is true.
    EndUser:
      type: object
      description: >
        The person your product acts for. Send a stable ID scoped to your
        platform, never an email

        or a name. Reflections stores only an HMAC of it.
      required:
        - id
      properties:
        id:
          type: string
          maxLength: 200
          description: >
            Your stable ID for the person, up to 200 characters. Never an email
            or a name.
        type:
          type: string
          enum:
            - consumer
            - business
          default: consumer
          description: >
            `consumer` for a person acting for themselves, `business` for one
            acting for a company.
    Execution:
      type: object
      description: >
        Which model will run, or ran, the request. Reflections records it as
        stated by the

        platform (`assurance: attested`).
      properties:
        provider:
          type: string
          maxLength: 100
          description: The model provider.
        model:
          type: string
          maxLength: 100
          description: The model's name at the provider.
        candidates:
          type: integer
          minimum: 1
          maximum: 16
          description: Outputs this request will produce.
        job_id:
          type: string
          maxLength: 200
          description: The provider's ID for the job.
    Duration:
      type: string
      description: An ISO 8601 duration, such as `PT60S` or `P30D`.
      example: P30D
    PromptHandling:
      type: object
      properties:
        mode:
          type: string
          enum:
            - full
            - redacted
            - withheld
          default: full
          description: >
            `full`: text is sent as is. `redacted`: you removed personal data
            first, and the

            digest covers the redacted text. `withheld`: no text is sent. Send
            each text input as

            `role`, `sha256` of its UTF-8 bytes and `media_type: text/plain`,
            and name the talent

            in `talent`, because names cannot be matched in text Reflections
            does not see. Rules

            that need the text are checked on the output instead.
        retention:
          type: string
          enum:
            - default
            - none
          default: default
          description: >-
            `none`: delete text as soon as the check is decided, even on `deny`
            or `escalate`.
    Metadata:
      type: object
      description: >-
        Up to 50 keys of your own, each up to 40 characters, values up to 500
        characters. Never put personal data here.
      additionalProperties:
        type: string
        maxLength: 500
      maxProperties: 50
    CheckStatus:
      type: string
      description: >
        `checking`: live evaluation has not finished; there is no decision yet.

        `allowed`, `denied`: decided. `escalated`: waiting for a person; it ends
        `allowed`, or

        `denied` with `review_declined` or, after `escalation.expires_at`,
        `hold_expired`.

        `consumed`: every allowed generation was used. `expired`: an allowed
        check's authorization

        expired unused. `cancelled`: you cancelled it.
      enum:
        - checking
        - allowed
        - denied
        - escalated
        - consumed
        - expired
        - cancelled
    Decision:
      type: string
      description: >
        `allow`: proceed and meet the obligations. `deny`: do not proceed.
        `escalate`: wait; a

        person with authority will decide, and an unanswered escalation becomes
        `deny`.
      enum:
        - allow
        - deny
        - escalate
    CheckTalent:
      type: object
      required:
        - talent
        - name
        - matched_by
        - confidence
        - decision
      properties:
        talent:
          type: string
          pattern: ^tal_[0-9a-hjkmnp-tv-z]{26}$
          description: The talent's ID.
        name:
          type: string
          description: The talent's name, to show your user.
        matched_by:
          type: string
          enum:
            - explicit
            - name
            - alias
            - indirect
            - reference_image
            - voice_sample
          description: >
            How the request invokes the talent: `explicit` from `talent`, `name`
            or `alias` in text,

            `indirect` for a reference such as a role, or `reference_image` or
            `voice_sample` from

            media.
        confidence:
          type: string
          enum:
            - exact
            - high
            - medium
            - low
          description: >
            How certain the match is. Every talent at `medium` or higher is
            treated as invoked.
        decision:
          description: >
            This talent's decision. The check's `decision` is the most
            restrictive across `talent`.

            Null while the check is `checking`.
          oneOf:
            - $ref: '#/components/schemas/Decision'
            - type: 'null'
        facets:
          type: array
          items:
            type: string
            pattern: ^fct_[0-9a-hjkmnp-tv-z]{26}$
          description: The talent's facets the use covers.
        license:
          type:
            - string
            - 'null'
          pattern: ^lic_[0-9a-hjkmnp-tv-z]{26}$
          description: >-
            The license that decided this talent's use. Null when no license
            applies.
        license_revision:
          type:
            - string
            - 'null'
          pattern: ^lrv_[0-9a-hjkmnp-tv-z]{26}$
          description: >-
            The revision of `license` that applied. Null when no license
            applies.
        terms_digest:
          description: The `terms_digest` of that revision. Null when no license applies.
          oneOf:
            - $ref: '#/components/schemas/Digest'
            - type: 'null'
        escalation:
          type:
            - string
            - 'null'
          pattern: ^esc_[0-9a-hjkmnp-tv-z]{26}$
          description: >-
            This talent's escalation, when their side must decide. Each
            escalated talent has their own.
    Reason:
      type: object
      required:
        - code
        - stage
        - sentence
      properties:
        code:
          $ref: '#/components/schemas/ReasonCode'
          description: A stable reason code. Branch on it.
        stage:
          type: string
          enum:
            - check
            - generation
            - session
          description: 'Where it was decided: `check`, `generation` or `session`.'
        talent:
          type: string
          pattern: ^tal_[0-9a-hjkmnp-tv-z]{26}$
          description: The talent the reason concerns.
        term:
          $ref: '#/components/schemas/Address'
          description: >-
            The license term or standing rule the reason rests on, as an
            address.
        sentence:
          type: string
          description: >-
            The reason in the license's own words. Show it to your user as
            written.
    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.
    Authorization:
      type: object
      description: >
        Proof that a check allowed a use. A generation tool or provider verifies
        `token` offline

        against the JWKS before it generates. For the initial live image
        submission, send the

        allowed `check` ID; the server reads its stored token. GenerationCreate
        has no separate

        authorization-token field.
      required:
        - token
        - max_generations
        - generations_used
        - expires_at
      properties:
        token:
          type: string
          description: A JWS with `typ` `tlp-auth+jwt`.
        max_generations:
          type: integer
          minimum: 1
          description: |
            How many generations it covers. A generation past it fails with `409
            authorization_consumed`.
        generations_used:
          type: integer
          minimum: 0
          description: How many generations have been submitted under it.
        expires_at:
          type: string
          format: date-time
          description: >
            When it expires, at most 15 minutes after it was issued. A
            generation after it fails

            with `409 check_expired`.
    Escalation:
      type: object
      required:
        - id
        - reason
        - reviewer
        - status
        - expires_at
      properties:
        id:
          type: string
          pattern: ^esc_[0-9a-hjkmnp-tv-z]{26}$
          description: The escalation's ID, `esc_` followed by 26 characters.
        reason:
          type: string
          enum:
            - judgment
            - unverifiable
            - evaluation_unavailable
            - release_review
          description: >
            `judgment`: a rule needs a person to read it. `unverifiable`: a
            protected attribute

            could not be confirmed. `evaluation_unavailable`: the check could
            not finish.

            `release_review`: every output under this license is released by a
            person.
        reviewer:
          type: string
          enum:
            - talent
            - representative
            - reflections
          description: >
            `talent`: the talent, or a representative whose mandate has
            `review_outputs`.

            `representative`: only the talent's representatives. `reflections`:
            Reflections trust

            and safety, under a platform license.
        status:
          type: string
          enum:
            - open
            - allowed
            - denied
            - expired
            - cancelled
          description: >
            `open` until it closes: `allowed` or `denied` by the reviewer,
            `expired` at

            `expires_at`, or `cancelled` when you cancel the check, withdraw the
            output, or another

            talent's escalation decides the check.
        expires_at:
          type: string
          format: date-time
          description: >
            When an unanswered escalation becomes `deny`: 7 days after it opens,
            or the license's

            shorter `escalation_window`.
        resolved_at:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            When the escalation was decided, expired or cancelled. Null while
            `open`.
        note:
          type:
            - string
            - 'null'
          maxLength: 500
          description: The reviewer's note, if they wrote one.
    Remedy:
      type: object
      description: What would change a `deny`.
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - license_request
            - license_change
            - disambiguate
            - retry_with_hold
          description: >
            `license_request`: no license covers this; request one.
            `license_change`: a license

            exists but is narrower; request a change. `disambiguate`: name the
            talent explicitly.

            `retry_with_hold`: retry with `on_escalate: hold` to let a person
            review.
        license:
          type: string
          pattern: ^lic_[0-9a-hjkmnp-tv-z]{26}$
          description: The license to change, for `license_change`.
        talent:
          type: string
          pattern: ^tal_[0-9a-hjkmnp-tv-z]{26}$
          description: The talent to send a license request to.
        suggested_scope:
          $ref: '#/components/schemas/LicenseScopeRequest'
          description: >
            The scope that would allow the use, ready to send as
            `requested_scope` on a license

            request.
    Digest:
      type: string
      description: A SHA-256 digest, `sha256:` followed by 64 lowercase hex characters.
      pattern: ^sha256:[0-9a-f]{64}$
    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.
    Sha256Hex:
      type: string
      description: A SHA-256 digest of bytes, as 64 lowercase hex characters.
      pattern: ^[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
    UseKind:
      type: string
      description: >
        How the talent appears. `depiction`: shown or heard. `impersonation`:
        speaks or writes as

        the talent. `endorsement`: implies the talent approves something.
        `reference`: talked

        about, without synthesis; needs no license.
      enum:
        - depiction
        - impersonation
        - endorsement
        - reference
    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
    ReasonCode:
      type: string
      description: >-
        Why a use was denied or escalated, or a session terminated. See the
        reason code catalog.
      enum:
        - no_license
        - license_pending_acceptance
        - license_revoked
        - license_suspended
        - window_not_started
        - window_ended
        - terms_unreadable
        - account_not_licensee
        - material_unavailable
        - adjustment_not_licensed
        - facet_not_licensed
        - kind_not_licensed
        - modality_not_licensed
        - purpose_not_licensed
        - channel_not_licensed
        - territory_not_licensed
        - commercial_use_not_licensed
        - platform_not_licensed
        - delivery_limit_reached
        - monthly_limit_reached
        - talent_prohibits
        - prohibited_appearance_change
        - prohibited_endorsement
        - prohibited_custom_term
        - identity_not_preserved
        - prohibited_speech
        - prohibited_motion
        - narration_mismatch
        - voice_rule
        - unsupported_rule
        - attribute_unverifiable
        - output_unverifiable
        - ambiguous_talent
        - review_required
        - unverifiable_request
        - evaluation_unavailable
        - authority_changed
        - provenance_failed
        - hold_expired
        - review_declined
        - review_expired
        - session_not_permitted
        - renewal_missed
        - sample_missed
    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
    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
    LicenseScopeRequest:
      type: object
      description: >-
        The scope you ask for. Omitted fields ask for nothing beyond the current
        license, or for the talent's defaults.
      properties:
        facets:
          type: array
          items:
            type: string
            pattern: ^fct_[0-9a-hjkmnp-tv-z]{26}$
          description: The facets you ask for, by ID.
        facet_types:
          type: array
          items:
            $ref: '#/components/schemas/FacetType'
          description: >
            The facet types you ask for, such as `likeness`, when you do not
            name `facets`.
        modalities:
          type: array
          items:
            $ref: '#/components/schemas/Modality'
          description: What you want to generate.
        kinds:
          type: array
          items:
            $ref: '#/components/schemas/UseKind'
          description: How the talent would appear.
        purposes:
          type: array
          items:
            $ref: '#/components/schemas/Purpose'
          description: What the outputs are for.
        commercial:
          type: boolean
          description: '`true` to ask for commercial use.'
        channels:
          type: array
          items:
            $ref: '#/components/schemas/Channel'
          description: >
            Where outputs would appear. For `change`, list every channel you
            want, not only the new

            ones.
        territories:
          type: array
          items:
            $ref: '#/components/schemas/Territory'
          description: Where outputs would appear, as ISO 3166-1 alpha-2 codes or `WW`.
        starts_at:
          type: string
          format: date-time
          description: When you want the license to come into force.
        ends_at:
          type: string
          format: date-time
          description: When you want the license to end.
        adjustments:
          type: array
          description: Adjustments you ask to be allowed.
          items:
            $ref: '#/components/schemas/AdjustmentKind'
        final_deliverables:
          type: integer
          minimum: 1
          description: How many outputs you want to deliver in total.
        sessions:
          type: boolean
          description: Ask for live sessions.
        material_access:
          type: boolean
          description: >
            `true` to ask to download the facets' reference material and send it
            to a model.
        platforms:
          type: array
          items:
            type: string
            pattern: ^acct_[0-9a-hjkmnp-tv-z]{26}$
          description: Platform accounts you want to run checks under the license.
        sublicense:
          type: string
          enum:
            - none
            - end_users_personal
          description: >
            `end_users_personal` to ask that a platform's end users may make
            personal,

            non-commercial outputs.
    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
    FacetType:
      type: string
      description: >
        `name`: the name in text. `likeness`: face and body in images and video.
        `voice`: the

        voice in speech. `twin`: a persona that speaks or writes as the talent.
        `knowledge`: a

        Volume of the talent's own words a model may draw on.
      enum:
        - name
        - likeness
        - voice
        - twin
        - knowledge
    AdjustmentKind:
      type: string
      description: A change the licensee may make to the talent's appearance or context.
      enum:
        - reframe
        - background_extension
        - lighting
        - text_overlay
        - body_and_age
        - expression
        - hair
        - pose
        - wardrobe
        - objects
        - skin_retouch
        - endorsement
  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:
    CheckAllow:
      summary: Allowed, with obligations
      value:
        id: chk_3m7p4r6s9t0wxyhk5zba2q8v1n
        object: check
        livemode: true
        status: allowed
        decision: allow
        talent:
          - talent: tal_9t0wxyhk5zba2q8v1m3n7p4r6s
            name: Maya Okafor
            matched_by: name
            confidence: high
            decision: allow
            facets:
              - fct_5zba2q8v1m3n7p4r6s9t0wxyhk
            license: lic_k5zba2q8v1m3n7p4r6s9t0wxyh
            license_revision: lrv_p4r6s9t0wxyhk5zba2q8v1m3n7
            terms_digest: >-
              sha256:39f18c8bef02b5226b9feaa92e526ed30b81b91650d8a10b503281b169f44431
        use:
          modality: image
          kind: depiction
          purpose: advertising
          commercial: true
          channels:
            - social
            - web
          territories:
            - US
            - CA
        reasons: []
        obligations:
          - type: generation_check
            required: all
          - type: hold_until_release
            reviewer: talent
          - type: draft_watermark
          - type: generation_instructions
            instructions:
              - >-
                Keep Maya Okafor the same person: face, skin tone and build
                unchanged.
              - Do not show alcohol or tobacco.
              - Do not imply she endorses any product other than the one shown.
            term: license:lic_k5zba2q8v1m3n7p4r6s9t0wxyh/terms.neverExtras
          - type: disclosure
            level: brand
            placement: both
            text: >-
              Made with AI. Maya Okafor's likeness used under license by
              Ridgeline.
          - type: c2pa_manifest
          - type: no_training
            material: outputs
          - type: usage_report
            units: placements
            within: P30D
        authorization:
          token: >-
            eyJhbGciOiJFUzI1NiIsImtpZCI6InJmbC0yMDI2LTEwLWRvY3MzIiwidHlwIjoidGxwLWF1dGgrand0In0.eyJhdWQiOiJhY2N0XzdwNHI2czl0MHd4eWhrNXpiYTJxOHYxbTNuIiwiZXhwIjoxNzkyMjYwOTAwLCJpYXQiOjE3OTIyNjAwMDAsImlzcyI6Imh0dHBzOi8vYXBwLnJlZmxlY3Rpb25zLmFpIiwianRpIjoiY2hrXzNtN3A0cjZzOXQwd3h5aGs1emJhMnE4djFuIiwic3ViIjoiYWNjdF8ycTh2MW0zbjdwNHI2czl0MHd4eWhrNXpiYSIsInRscCI6eyJkZWNpc2lvbiI6ImFsbG93IiwiZXUiOiIzZjljMWE3ZTViMmQ4ZjQwNjFjM2U5YTdiNWQyZjgwMTZlNGM5YTNiN2QxZjVlMmM4YTZiNGQwZjllM2M3YTE1IiwiZXhlY3V0aW9uIjp7Im1vZGVsIjoiaW1hZ2UtbW9kZWwtMyIsInByb3ZpZGVyIjoiZXhhbXBsZS1pbWFnZS1wcm92aWRlciJ9LCJmYWNldHMiOlsiZmN0XzV6YmEycTh2MW0zbjdwNHI2czl0MHd4eWhrIl0sImxpY2Vuc2VzIjpbeyJsaWNlbnNlIjoibGljX2s1emJhMnE4djFtM243cDRyNnM5dDB3eHloIiwicmV2aXNpb24iOiJscnZfcDRyNnM5dDB3eHloazV6YmEycTh2MW0zbjciLCJ0YWxlbnQiOiJ0YWxfOXQwd3h5aGs1emJhMnE4djFtM243cDRyNnMiLCJ0ZXJtc19kaWdlc3QiOiJzaGEyNTY6MzlmMThjOGJlZjAyYjUyMjZiOWZlYWE5MmU1MjZlZDMwYjgxYjkxNjUwZDhhMTBiNTAzMjgxYjE2OWY0NDQzMSJ9XSwibWF4X2dlbmVyYXRpb25zIjo0LCJvYmxpZ2F0aW9ucyI6WyJnZW5lcmF0aW9uX2NoZWNrIiwiaG9sZF91bnRpbF9yZWxlYXNlIiwiZHJhZnRfd2F0ZXJtYXJrIiwiZ2VuZXJhdGlvbl9pbnN0cnVjdGlvbnMiLCJkaXNjbG9zdXJlIiwiYzJwYV9tYW5pZmVzdCIsIm5vX3RyYWluaW5nIiwidXNhZ2VfcmVwb3J0Il0sInJlcXVlc3RfZGlnZXN0Ijoic2hhMjU2OmJmOTQ4MTc3NjZkNTZkOTIyMTFkMTJmNWZmNTFhM2RjMWE2ZDVjYjRiZTI4Nzc0MTdiMDgyNTFmZTM4YzM4NmEiLCJ0YWxlbnQiOlsidGFsXzl0MHd4eWhrNXpiYTJxOHYxbTNuN3A0cjZzIl0sInVzZSI6eyJjaGFubmVscyI6WyJzb2NpYWwiLCJ3ZWIiXSwiY29tbWVyY2lhbCI6dHJ1ZSwia2luZCI6ImRlcGljdGlvbiIsIm1vZGFsaXR5IjoiaW1hZ2UiLCJwdXJwb3NlIjoiYWR2ZXJ0aXNpbmciLCJ0ZXJyaXRvcmllcyI6WyJVUyIsIkNBIl19LCJ2ZXIiOiIxLjAifX0.sbcXipODRBifCQEGJacDUoBBDzW1YzLdbKAv-ky0fZXjfGRTx4JQd2nap26LYy7PlMRod-7rfqLFgmWE4tutdg
          max_generations: 4
          generations_used: 0
          expires_at: '2026-10-17T18:15:00Z'
        escalation: null
        remedy: null
        request_digest: >-
          sha256:bf94817766d56d92211d12f5ff51a3dc1a6d5cb4be2877417b08251fe38c386a
        licensee: acct_2q8v1m3n7p4r6s9t0wxyhk5zba
        platform: acct_7p4r6s9t0wxyhk5zba2q8v1m3n
        session: null
        receipt: rcpt_0wxyhk5zba2q8v1m3n7p4r6s9t
        metadata: {}
        created_at: '2026-10-17T18:00:00Z'
    CheckDeny:
      summary: Denied, with a remedy
      value:
        id: chk_8v1m3n7p4r6s9t0wxyhk5zba2q
        object: check
        livemode: true
        status: denied
        decision: deny
        talent:
          - talent: tal_9t0wxyhk5zba2q8v1m3n7p4r6s
            name: Maya Okafor
            matched_by: name
            confidence: high
            decision: deny
            facets:
              - fct_5zba2q8v1m3n7p4r6s9t0wxyhk
            license: lic_k5zba2q8v1m3n7p4r6s9t0wxyh
            license_revision: lrv_p4r6s9t0wxyhk5zba2q8v1m3n7
            terms_digest: >-
              sha256:39f18c8bef02b5226b9feaa92e526ed30b81b91650d8a10b503281b169f44431
        use:
          modality: image
          kind: depiction
          purpose: advertising
          commercial: true
          channels:
            - social
            - web
            - tv
          territories:
            - US
            - CA
        reasons:
          - code: channel_not_licensed
            stage: check
            talent: tal_9t0wxyhk5zba2q8v1m3n7p4r6s
            term: license:lic_k5zba2q8v1m3n7p4r6s9t0wxyh/terms.channels
            sentence: This license covers social media and the brand's own website.
        obligations: []
        authorization: null
        escalation: null
        remedy:
          type: license_change
          license: lic_k5zba2q8v1m3n7p4r6s9t0wxyh
          talent: tal_9t0wxyhk5zba2q8v1m3n7p4r6s
          suggested_scope:
            channels:
              - social
              - web
              - tv
        request_digest: >-
          sha256:b2d4f6a8c0e2b4d6f8a0c2e4b6d8f0a2c4e6b8d0f2a4c6e8b0d2f4a6c8e0b2d4
        licensee: acct_2q8v1m3n7p4r6s9t0wxyhk5zba
        platform: acct_7p4r6s9t0wxyhk5zba2q8v1m3n
        session: null
        receipt: rcpt_5zba2q8v1m3n7p4r6s9t0wxyhk
        metadata: {}
        created_at: '2026-10-17T18:02:00Z'
    CheckEscalate:
      summary: Escalated to the talent
      value:
        id: chk_r6s9t0wxyhk5zba2q8v1m3n7p4
        object: check
        livemode: true
        status: escalated
        decision: escalate
        talent:
          - talent: tal_9t0wxyhk5zba2q8v1m3n7p4r6s
            name: Maya Okafor
            matched_by: name
            confidence: high
            decision: escalate
            facets:
              - fct_5zba2q8v1m3n7p4r6s9t0wxyhk
            license: lic_k5zba2q8v1m3n7p4r6s9t0wxyh
            license_revision: lrv_p4r6s9t0wxyhk5zba2q8v1m3n7
            terms_digest: >-
              sha256:39f18c8bef02b5226b9feaa92e526ed30b81b91650d8a10b503281b169f44431
            escalation: esc_t0wxyhk5zba2q8v1m3n7p4r6s9
        use:
          modality: image
          kind: depiction
          purpose: advertising
          commercial: true
          channels:
            - social
          territories:
            - US
        reasons:
          - code: prohibited_custom_term
            stage: check
            talent: tal_9t0wxyhk5zba2q8v1m3n7p4r6s
            term: license:lic_k5zba2q8v1m3n7p4r6s9t0wxyh/terms.neverExtras
            sentence: Do not show alcohol or tobacco.
        obligations: []
        authorization: null
        escalation:
          id: esc_t0wxyhk5zba2q8v1m3n7p4r6s9
          reason: judgment
          reviewer: talent
          status: open
          expires_at: '2026-10-24T18:04:00Z'
          resolved_at: null
          note: null
        remedy: null
        request_digest: >-
          sha256:c3e5a7b9d1f3c5e7a9b1d3f5c7e9a1b3d5f7c9e1a3b5d7f9c1e3a5b7d9f1c3e5
        licensee: acct_2q8v1m3n7p4r6s9t0wxyhk5zba
        platform: acct_7p4r6s9t0wxyhk5zba2q8v1m3n
        session: null
        receipt: null
        metadata: {}
        created_at: '2026-10-17T18:04:00Z'
    CheckChecking:
      summary: Live evaluation still running
      value:
        id: chk_3m7p4r6s9t0wxyhk5zba2q8v1n
        object: check
        livemode: true
        status: checking
        decision: null
        talent:
          - talent: tal_9t0wxyhk5zba2q8v1m3n7p4r6s
            name: Licensed talent
            matched_by: explicit
            confidence: exact
            decision: null
            facets: []
            license: lic_k5zba2q8v1m3n7p4r6s9t0wxyh
            license_revision: lrv_p4r6s9t0wxyhk5zba2q8v1m3n7
            terms_digest: >-
              sha256:39f18c8bef02b5226b9feaa92e526ed30b81b91650d8a10b503281b169f44431
            escalation: null
        use:
          modality: image
          kind: depiction
          purpose: advertising
          commercial: true
          channels:
            - social
            - web
          territories:
            - US
            - CA
        reasons: []
        obligations: []
        authorization: null
        escalation: null
        remedy: null
        request_digest: >-
          sha256:bf94817766d56d92211d12f5ff51a3dc1a6d5cb4be2877417b08251fe38c386a
        licensee: acct_2q8v1m3n7p4r6s9t0wxyhk5zba
        platform: acct_2q8v1m3n7p4r6s9t0wxyhk5zba
        session: null
        receipt: null
        metadata: {}
        created_at: '2026-10-17T18:00:00Z'
  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
    Forbidden:
      description: >-
        The key may not do this, the licensee is not connected, or live mode is
        not activated for this operation (`live_not_activated`).
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.reflections.ai/errors/account_not_connected
            title: The licensee has not connected your platform
            status: 403
            code: account_not_connected
            detail: >-
              acct_2q8v1m3n7p4r6s9t0wxyhk5zba has no active connection with your
              account.
            request_id: req_8f2k4m6p8r0t2v4x6z8b0d2f4h
    NotFound:
      description: No such object for this account.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.reflections.ai/errors/resource_not_found
            title: No such object
            status: 404
            code: resource_not_found
            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'
  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.