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

# Reason codes

> Every reason a use is denied or escalated, its stage, whether a remedy comes with it, and what to show.

When a check, a generation or a session sample is not `allow`, its `reasons` say why. Reasons are
part of a decision, not errors: they arrive in `200` responses and in events.

```json theme={null}
{
  "decision": "deny",
  "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."
    }
  ],
  "remedy": {
    "type": "license_change",
    "license": "lic_k5zba2q8v1m3n7p4r6s9t0wxyh",
    "talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
    "suggested_scope": { "channels": ["social", "web", "tv"] }
  }
}
```

| Field | Meaning |
| - | - |
| `code` | The reason code. Branch on it. |
| `stage` | Where it was decided: `check`, `generation` or `session`. |
| `talent` | The talent it concerns, when there are several. |
| `term` | The license term or standing rule it rests on, as an address. |
| `sentence` | The reason in the license's own words. Show it to your user as written. |

## Remedies

A `remedy` says what would change a `deny`. Only checks carry one, including the check behind a
session. A `license_request` or `license_change` remedy appears only when the talent accepts
requests through the API.

| `remedy.type` | What to offer |
| - | - |
| `license_request` | No license covers the use. Offer to [request a license](/api-reference/license-requests/request-a-license), with `check` set to this check. |
| `license_change` | A license exists but is narrower. Offer a request with `kind: change`, `license`, and `suggested_scope` as the starting scope. |
| `disambiguate` | The request could mean more than one talent. Ask your user who they meant, then check again with `talent` or `exclude_talent`. |
| `retry_with_hold` | The use needs a person, and you sent `on_escalate: "deny"`. Offer to send it for review with `on_escalate: "hold"`. |

## What to show

Always show `sentence` as written; do not rewrite it into your own words. The tables below add
what to offer beside the sentence.
If you receive a code that is not listed here, show the sentence and offer nothing else.

### License and window

| Code | Stage | Meaning | Remedy | Offer |
| - | - | - | - | - |
| `no_license` | check, session | The talent requires a license for this use, and you hold none. | `license_request` | A license request. |
| `license_pending_acceptance` | check, session | The talent's side signed the license, but the licensee has not accepted it yet. | None | The licensee accepts it at the license's `acceptance_url`. |
| `license_revoked` | check, generation, session | The license was revoked. | None | Nothing. Do not retry under this license. |
| `license_suspended` | check, generation, session | The talent or a representative paused the license. | None | Try again after `license.resumed`. |
| `window_not_started` | check, generation, session | The license window has not started. | None | Try again after `scope.window.starts_at`. |
| `window_ended` | check, generation, session | The license window ended. | `license_change` | A renewal request. |
| `terms_unreadable` | check | Reflections could not read the signed terms. | None | Try again later. Contact [support](/production/support) with the `request_id`. |
| `account_not_licensee` | check | The license named in the check belongs to a different licensee. | None | Nothing; fix `license` or `Reflections-Account`. |
| `material_unavailable` | check, generation | The reference material behind the facet is unavailable. | None | Try again later. |
| `platform_not_licensed` | check | No license the licensee holds covers this talent on your platform. | `license_change` | A request to add your platform. |

`platform_not_licensed` is a deny reason in a `200` response. It is different from the error
[`403 platform_not_permitted`](/api-reference/errors#403-forbidden), which you receive instead of a
decision when the check names a `license` explicitly and that license excludes your platform.

### Scope

| Code | Stage | Meaning | Remedy | Offer |
| - | - | - | - | - |
| `facet_not_licensed` | check | The license does not cover this facet, such as a voice under a likeness license. | `license_change` | A request for the facet. |
| `kind_not_licensed` | check | The license does not cover this kind of use, such as `endorsement` or `impersonation`. | `license_change` | A request for the kind, or a use of a kind the license covers. |
| `modality_not_licensed` | check | The license does not cover this modality. | `license_change` | A request for the modality. |
| `purpose_not_licensed` | check | The license does not cover this purpose. | `license_change` | A request for the purpose. |
| `channel_not_licensed` | check | The license does not cover one of the channels. | `license_change` | A request for the channels, or a narrower use. |
| `territory_not_licensed` | check | The license does not cover one of the territories. | `license_change` | A request for the territories, or a narrower use. |
| `commercial_use_not_licensed` | check | The license covers only non-commercial use. | `license_change` | A request for commercial use. |
| `adjustment_not_licensed` | check | The request asks for a change to the talent's appearance or context the license does not allow. | `license_change` | A request for the adjustment, or a prompt without it. |
| `delivery_limit_reached` | generation | Every output the license allows (`final_deliverables`) was delivered. | None | A change request that raises the limit. |
| `monthly_limit_reached` | check | The license's monthly limit is used up. | `license_change` | Wait for next month, or request a higher limit. |
| `session_not_permitted` | session | The license does not allow live sessions, or it holds every output for release. | `license_change`, on the session's check | A request for sessions. |

### The talent's rules

| Code | Stage | Meaning | Remedy | Offer |
| - | - | - | - | - |
| `talent_prohibits` | check, session | The talent's standing rules prohibit this use. No license can allow it. | None | Nothing. Do not offer a license request. |
| `prohibited_appearance_change` | check, generation | The request or the output changes the talent's appearance in a way the license prohibits. | None | A prompt without the change. |
| `prohibited_endorsement` | check, generation | The request or the output implies an endorsement the license prohibits. | None | A prompt without the endorsement. |
| `prohibited_custom_term` | check, generation, session | The request or the output breaks a rule the talent wrote. `sentence` is the rule. | None | A prompt that keeps the rule. |
| `unsupported_rule` | check | A rule the talent wrote for this modality cannot be checked on the output, so the use cannot start. | None | Nothing for this modality. |

### The output

| Code | Stage | Meaning | Remedy | Offer |
| - | - | - | - | - |
| `identity_not_preserved` | generation | The output does not keep the talent the same person. | None | Generate again. |
| `prohibited_speech` | generation, session | The output contains speech the license does not cover, or could not be shown to be silent. | None | Generate again without speech. |
| `prohibited_motion` | generation | The output contains motion the license does not cover. | None | Nothing for video under this license. |
| `narration_mismatch` | generation | The spoken narration does not match the approved words. | None | Generate again from the approved script. |
| `voice_rule` | generation | The output pairs the talent's likeness with a voice that is not their licensed voice. | None | Use the licensed voice, or a narrator who is clearly someone else. |
| `attribute_unverifiable` | generation | A protected attribute, such as `identity.samePerson`, could not be confirmed on the output, for example while an evaluator was unavailable. | None | Do not deliver this output. Generate again later. |
| `output_unverifiable` | generation | A fixed creation condition in the signed license could not be confirmed on the output. `term` identifies its signed field. | None | Do not deliver this output. Submit another output that can be checked. |
| `provenance_failed` | generation | The output's provenance could not be produced, so it cannot be delivered. | None | Submit the output again. |
| `authority_changed` | generation | The license was narrowed after the check, and the output falls outside it. | None | Run a new check. |

### Which talent

| Code | Stage | Meaning | Remedy | Offer |
| - | - | - | - | - |
| `ambiguous_talent` | check | The inputs could mean more than one talent. | `disambiguate` | Ask who they meant. |

### Live sessions

| Code | Stage | Meaning | Remedy | Offer |
| - | - | - | - | - |
| `renewal_missed` | session | The session token expired without a renewal. The session's status is `terminated`. | None | A new session, renewed every `renew_every`. |
| `sample_missed` | session | No sample arrived by the `act_by` of a `sample_overdue` warning, so the output could not be checked. The session's status is `terminated`. | None | A new session, sampled as `sampling` requires. |

### Review and evaluation

| Code | Stage | Meaning | Remedy | Offer |
| - | - | - | - | - |
| `review_required` | check | The use needs a person to decide, and you sent `on_escalate: "deny"`. | `retry_with_hold` | Send it for review. |
| `unverifiable_request` | check | A protected attribute could not be confirmed from the request. The check escalates with `escalation.reason: unverifiable`. | None | Wait for the reviewer. |
| `evaluation_unavailable` | check, session | The check could not finish. A check escalates with `escalation.reason: evaluation_unavailable`; a session denies. | None | Wait for the reviewer, or try the session again later. |
| `hold_expired` | check | Nobody answered the escalation before `escalation.expires_at`. The check's status is `denied`. | None | A new check. |
| `review_declined` | check, generation | The reviewer declined the use or the output. The check or generation's status is `denied`. `escalation.note` holds their note, if any. | None | Nothing for this request. |
| `review_expired` | generation | A held output was not released within its window. The generation's status is `expired` and its decision `deny`. | None | Generate and submit again. |

## Related

<Columns cols={2}>
  <Card title="Decisions" icon="scale-balanced" href="/concepts/decisions">
    `allow`, `deny` and `escalate`, at each stage.
  </Card>

  <Card title="Handle escalations" icon="bolt" href="/build/handling-escalations">
    Pending states, webhooks and `on_escalate`.
  </Card>

  <Card title="Errors" icon="ban" href="/api-reference/errors">
    When a request cannot be evaluated at all.
  </Card>

  <Card title="What we enforce" icon="shield-check" href="/concepts/what-we-enforce">
    Checked and recorded terms.
  </Card>
</Columns>


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