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

# API reference

> The base URL, test and live mode, the objects, and the conventions every endpoint shares.

This reference defines the target Talent API contract and labels every operation's current
availability. Test keys serve a **fictional sandbox**. Recorded production acceptance covers live
account and license reads. The initial live image implementation described below is deployed;
signing activation and production acceptance of that journey are not established.
Start with the [working quickstart](/quickstart) for the sandbox.

Pages are generated from one OpenAPI document at `/api-reference/openapi.yaml`. Its
`x-reflections-availability` field distinguishes source support in each mode from planned contracts;
it does not establish production activation.
A supported endpoint may still have unsupported input forms; read its availability notice.
Native TypeScript `fetch`, Python standard-library and Go `net/http` samples need no Reflections SDK.

For each new logical POST, generate a UUID once and save it with the request body. Set the
operation-specific environment variable named in the sample, such as
`REFLECTIONS_CREATE_CHECK_IDEMPOTENCY_KEY`. Keep the same value and body on retries; choose a new
value for a new request. Object IDs in endpoint examples are illustrative: replace them with the
IDs your earlier calls returned. The [quickstart](/quickstart) does both automatically.

## Base URL

```text theme={null}
https://app.reflections.ai/v1
```

The sandbox accepts JSON (`Content-Type: application/json`). File uploads and multipart
verification are planned. Responses are JSON, and errors are
[problem details](/api-reference/errors) (`application/problem+json`).

Every `/v1` endpoint is under the base URL. A few routes are **not** under `/v1`: they are at the
origin root, `https://app.reflections.ai`. **Only discovery and JWKS are currently served from this
table**; the session stream, Talent API OAuth and Talent API MCP are planned:

| Full URL | What it is |
| - | - |
| `wss://app.reflections.ai/v1/sessions/{session_id}/stream` | The [session stream](/api-reference/realtime/session-stream) for a live session |
| `https://app.reflections.ai/.well-known/talent-license` | The [discovery document](/api-reference/formats/discovery) |
| `https://app.reflections.ai/.well-known/jwks.json` | The keys that sign tokens and receipts, described with [discovery](/api-reference/formats/discovery). Not under `/v1`: `/v1/.well-known/jwks.json` returns `404` |
| [`/oauth/authorize`](/api-reference/oauth/authorize-a-client) | Where a licensee approves a [connection](/api-reference/authentication#connect-a-licensee-with-oauth), and where an agent's user approves an MCP client |
| [`/oauth/token`](/api-reference/oauth/create-an-access-token) | Access tokens for [MCP](/api-reference/mcp/overview) clients and [RSL](/standard/interop/rsl) clients |
| [`/oauth/register`](/api-reference/oauth/register-a-client) | Client registration for MCP and RSL clients |
| [`/oauth/introspect`](/api-reference/oauth/introspect-a-token) | Where a content host checks an RSL `License` token |
| [`/oauth/revoke`](/api-reference/oauth/revoke-a-token) | Token revocation, when a person signs out of a client |
| [`/.well-known/oauth-authorization-server`](/api-reference/oauth/retrieve-the-authorization-server-metadata) | The OAuth server metadata (RFC 8414) |
| [`/.well-known/oauth-protected-resource/mcp`](/api-reference/oauth/retrieve-the-mcp-servers-resource-metadata) | The MCP server's resource metadata (RFC 9728) |
| `/mcp` | The [MCP server](/api-reference/mcp/overview) for agents |

The OAuth and `/mcp` paths in the table are also at the origin root.

## Test and live mode

Test keys (`rk_test_`) return objects with `livemode: false` and use [fictional fixtures](/sandbox).
They cannot approve use of a real person's identity. Create a test or live key in the
[dashboard](https://app.reflections.ai/developers/keys); keep it on your server. A key needs a
Reflections account: sign in with either option on the sign-in page, and you return to the keys page.

The live reads are:

| Operation | What it returns |
| - | - |
| [`GET /v1/account`](/api-reference/account/retrieve-your-account) | The account that owns the key |
| [`GET /v1/licenses`](/api-reference/licenses/list-licenses) | Licenses whose sole licensee is that account; with `role=issuer`, licenses the account issued as talent |
| [`GET /v1/licenses/{license_id}`](/api-reference/licenses/retrieve-a-license) | One license the account holds or issued; use an ID from a list response |
| [`GET /v1/generations?license=…`](/api-reference/generations/list-generations) | The state of each output submitted through the API under a license the account holds or issued: status, decision, receipt and release status only |

These live objects carry `livemode: true`. License reads require `licenses:read` on a restricted
key; the output list requires `generations:read` or `generations:write`. A talent sees no prompt,
reference, bytes, execution or metadata of the licensee's outputs. The list includes each decided
output's receipt ID, and the public receipt shows its `request_digest` and `artifact_sha256`. A
summary stays listable after the generation's private details are deleted, when
`GET /v1/generations/{generation_id}` returns `404`. Delegated connections
are planned: the caller must hold or have issued the license. Responses expose the
current signed revision's identity and digest, with only the [supported scope fields](/concepts/licenses#live-license-reads).
They expose no private reference IDs or source media. Omitted fields grant nothing.

### Initial live image implementation

Live image checks, output submission and receipts are built but not yet activated: until activation,
a live `POST /v1/checks` or `POST /v1/generations` returns `403`
[`live_not_activated`](/api-reference/errors#live_not_activated). Retrying does not help; use a test
key until Reflections confirms activation. The source supports six operations for this journey.

| Operation | Initial live behavior |
| - | - |
| [`POST /v1/checks`](/api-reference/checks/create-a-check) | Evaluate one owned license and one declared image request; a pending check returns `202` with `status: "checking"`, so retry with the same body and key |
| [`GET /v1/checks/{check_id}`](/api-reference/checks/retrieve-a-check) | Read the caller's check and its current authorization consumption or expiry |
| [`POST /v1/generations`](/api-reference/generations/create-a-generation) | Submit one inline PNG; every successful POST returns the same accepted `202` response |
| [`GET /v1/generations/{generation_id}`](/api-reference/generations/retrieve-a-generation) | Read evaluation, talent review and the final decision |
| [`GET /v1/receipts/{receipt_id}`](/api-reference/receipts/retrieve-a-receipt) | Public signed receipt and current use status, without private request metadata |
| [`POST /v1/verifications`](/api-reference/verifications/verify-content) | Public JSON verification by live receipt ID or JWS; digest lookup requires the owning account's live key |

The check requires one explicit license, text inputs totaling at most **64 KiB**, image depiction,
commercial advertising or branded content, `execution.candidates: 1`, and `on_escalate: "deny"`.
Every channel and territory must match the signed scope; only signed `WW` means worldwide.
The provider and model must match the later generation. `job_id` is optional and can be supplied
after the provider starts the job. Generations accept only an inline still PNG, at most **7 MiB**
decoded, with its exact SHA-256. Reflections evaluates the submitted bytes; it does not render an
image or fetch an output from a provider or URL.

The license must newly sign `externalCreation: "images.v1"` and
`externalCreationPostRevocation: "retain"`. Existing signatures grant neither by omission.
Every image requires the talent's actual release before `decision: "allow"`; a successful upload
or evaluator result is insufficient. Live signing additionally requires protected operator
activation after the public key's 30-day publication period. That activation is not established.

Private check and generation detail remains available while pending and for 24 hours after its
terminal retention boundary, then returns `404`. Signed receipts have a separate seven-year
retention period. See [Privacy](/concepts/privacy) and
[production qualification](/production/conformance#initial-live-image-implementation).

Live check/generation lists, cancellation and withdrawal, revisions, talent/facets, delegated
connections, revocation feeds, files, video, OAuth and webhooks remain unsupported. Receipt retrieval is keyless in both modes. Verification looks only in the caller's mode: a test
receipt needs a test key, and verifying it with a live key or no key returns `result: "not_found"`. Reading a live license
alone does not authorize generation.

## Two sides

Most endpoints serve the side that uses a license: licensees and the platforms that act for them
check uses, submit outputs, report usage and honor revocations. The talent side serves
representatives, such as agencies and managers, acting for a talent under a
[mandate](/api-reference/mandates/list-mandates): the [escalation](/api-reference/escalations/list-escalations)
queue, [license drafts](/api-reference/license-drafts/draft-a-license), declining requests,
suspending and revoking licenses, and confirming or disputing statements. A license is only ever
signed by a person, on a hosted page. See [Talent representatives](/guides/talent-representatives).

## Headers

| Header | Sent by | Use |
| - | - | - |
| `Authorization` | You | `Bearer rk_…`. See [Authentication](/api-reference/authentication). |
| `Reflections-Version` | You | The dated version, `2026-10-15`. See [Versioning](/api-reference/versioning). |
| `Idempotency-Key` | You | On every `POST`. See [Idempotency](/api-reference/idempotency). |
| `Reflections-Account` | You | The `acct_` ID of a connected licensee you act for. See [Authentication](/api-reference/authentication#act-for-a-licensee). |
| `Request-Id` | Reflections | `req_…`. Include it when you contact [support](/production/support). |
| `RateLimit`, `RateLimit-Policy` | Reflections | Your remaining quota. See [Rate limits](/api-reference/rate-limits). |

## Objects

Every object has an `id` and an `object` field naming its type. IDs are a prefix, an underscore and
26 characters of lowercase Crockford base32, which has no `i`, `l`, `o` or `u`, such as
`chk_3m7p4r6s9t0wxyhk5zba2q8v1n`. Treat them as opaque strings.

| Object | `object` | ID prefix | Endpoints |
| - | - | - | - |
| Account | `account` | `acct_` | [Account](/api-reference/account/retrieve-your-account) |
| Talent | `talent` | `tal_` | [Talent](/api-reference/talent/list-talent) |
| Name index | `talent_index` | none | [Talent](/api-reference/talent/list-talent) |
| Facet | `facet` | `fct_` | [Facets](/api-reference/facets/list-talent-facets) |
| Facet material | `facet_material` | none; items are `mat_` | [Facets](/api-reference/facets/list-talent-facets) |
| Resolution | `resolution` | `res_` | [Resolutions](/api-reference/resolutions/resolve-talent) |
| License | `license` | `lic_` | [Licenses](/api-reference/licenses/list-licenses) |
| License revision | `license_revision` | `lrv_` | [Licenses](/api-reference/licenses/list-licenses) |
| License request | `license_request` | `lrq_` | [License requests](/api-reference/license-requests/request-a-license) |
| Connection | `connection` | `con_` | [Connections](/api-reference/connections/list-connections) |
| File | `file` | `file_` | [Files](/api-reference/files/upload-a-file) |
| Check | `check` | `chk_` | [Checks](/api-reference/checks/create-a-check) |
| Generation | `generation` | `gen_` | [Generations](/api-reference/generations/create-a-generation) |
| Session | `session` | `ses_` | [Sessions](/api-reference/sessions/create-a-session) |
| Session sample | `session_sample` | `smp_` | [Sessions](/api-reference/sessions/create-a-session) |
| Receipt | `receipt` | `rcpt_` | [Receipts](/api-reference/receipts/retrieve-a-receipt) |
| Verification | `verification` | `vrf_` | [Verifications](/api-reference/verifications/verify-content) |
| Revocation | `revocation` | `rvk_` | [Revocations](/api-reference/revocations/list-revocations) |
| Usage record | `usage_record` | `ur_` | [Usage records](/api-reference/usage-records/report-usage) |
| Statement | `statement` | `stmt_` | [Statements](/api-reference/statements/list-statements) |
| Mandate | `mandate` | `mnd_` | [Mandates](/api-reference/mandates/list-mandates) |
| Escalation | `escalation` | `esc_` | [Escalations](/api-reference/escalations/list-escalations) |
| License draft | `license_draft` | `ldr_` | [License drafts](/api-reference/license-drafts/draft-a-license) |
| Webhook endpoint | `webhook_endpoint` | `we_` | [Webhook endpoints](/api-reference/webhook-endpoints/create-a-webhook-endpoint) |
| Event | `event` | `evt_` | [Events](/api-reference/events/list-events) |

An escalation also appears inside its check or generation, as `escalation`. Some IDs appear only
inside other objects and have no endpoint of their own:

| Prefix | Where it appears |
| - | - |
| `pay_` | A payment, in a statement's `payments` |
| `mat_` | A material item, in facet material `items` |
| `req_` | A request, in the `Request-Id` header and an error's `request_id` |

The [test helpers](/api-reference/test-helpers/resolve-an-escalation) act as a talent or a
reviewer in test mode. They create no objects of their own.

## Lists

Every list endpoint returns the same envelope, newest first:

```json theme={null}
{
  "object": "list",
  "data": [
    { "id": "chk_3m7p4r6s9t0wxyhk5zba2q8v1n", "object": "check", "decision": "allow" }
  ],
  "has_more": true,
  "next_cursor": "Y2hrXzNtN3A0cjZz…"
}
```

Pass `next_cursor` as `cursor` to read the next page. See [Pagination](/api-reference/pagination).

## IDs, not nested objects

A field that names another object holds its ID. A check's `receipt` is `rcpt_…`, a generation's
`check` is `chk_…`, and a license's `talent` is `tal_…`. There is no `expand` parameter: retrieve
the other object from its own endpoint.

A response embeds a nested object only where you need it in the same call:

| Object | Embeds |
| - | - |
| Check | `talent` (one entry per talent found), `authorization`, `escalation`, `remedy` |
| Generation | `findings`, `escalation`, `c2pa` |
| Session | `sampling`, `termination` |
| Talent | `posture`, `representation`, and a summary of each facet in `facets` |
| License | `scope`, the normalized terms of the current revision |
| Verification | The matching `receipt`, in full |
| Event | The object the event is about, in `data.object` |

## Formats

| Value | Format | Example |
| - | - | - |
| Timestamps | RFC 3339, always UTC | `"2026-10-17T18:00:00Z"` |
| Durations | ISO 8601 | `"PT60S"`, `"P30D"` |
| Money | An integer in the currency's smallest unit, with a lowercase ISO 4217 currency | `{ "amount": 250000, "currency": "usd" }` is \$2,500.00 |
| Document and request digests | `sha256:` and 64 lowercase hex characters | `terms_digest`, `request_digest` |
| Byte digests | 64 lowercase hex characters | `artifact.sha256`, `artifact_sha256` |
| Territories | ISO 3166-1 alpha-2, or `WW` for worldwide | `"US"` |
| Addresses | `license:<id>/terms.<key>` for a term, `talent:<id>` for a talent's standing rule | `"license:lic_k5zba2q8v1m3n7p4r6s9t0wxyh/terms.channels"` |
| Metadata | Up to 50 string keys of your own, values up to 500 characters | `{ "campaign": "spring-trail" }` |

A statement's `amount_due`, `amount_paid` and line `amount` values are integers in the statement's
`currency`. Never put personal data in `metadata`.

## Where to go next

<Columns cols={2}>
  <Card title="Authentication" icon="key" href="/api-reference/authentication">
    Keys, scopes, and acting for a licensee.
  </Card>

  <Card title="Errors" icon="ban" href="/api-reference/errors">
    The problem format and every error code.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/api-reference/webhooks/overview">
    Signatures, retries, ordering and replay.
  </Card>

  <Card title="Authorization token" icon="shield-check" href="/api-reference/formats/authorization-token">
    The token a tool verifies before it generates.
  </Card>
</Columns>


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