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

# Agent builders

> Pass the check's authorization with each tool call, and verify it inside the tool that generates.

<Note>
  Planned integration guide. The Talent API MCP server and its OAuth flow are not available.
  Agents can call the served test-mode HTTP endpoints directly; the existing Licensed Studio MCP
  and docs-search MCP are separate services.
  Start with the [runnable quickstart](/quickstart) and [sandbox support matrix](/sandbox).
</Note>

In an agent, the model chooses which tools to call, so protection for a talent cannot depend on
the model remembering to check first. The design answer is that the authorization travels with
the call: the agent checks a use, passes the token it receives to the generation tool, and the
tool verifies that token before it runs. The check tells the agent what is allowed. The tool's
verification is what enforces it.

```mermaid theme={null}
sequenceDiagram
    participant A as Agent
    participant R as Reflections
    participant T as Generation tool
    A->>R: check_use
    R-->>A: decision and authorization
    A->>T: Tool call with authorization
    T->>T: Verify offline, count, generate
    T->>R: Submit the output
    R-->>T: allow and receipt
    T-->>A: Output, receipt, disclosure
```

## HTTP now, MCP planned

An agent can call the served sandbox HTTP operations from its orchestrator today.
The proposed Talent API MCP interface would wrap HTTP operations as the tools below. Its server,
OAuth discovery and client registration are not deployed; do not configure an MCP client with
`https://app.reflections.ai/mcp` expecting these tools.

| Tool | Same as |
| - | - |
| `resolve_talent` | `POST /v1/resolutions` |
| `check_use` | `POST /v1/checks` |
| `submit_generation` | `POST /v1/generations` |
| `get_check` | `GET /v1/checks/{check_id}` |
| `get_generation` | `GET /v1/generations/{generation_id}` |
| `get_license`, `list_licenses` | `GET /v1/licenses/{license_id}`, `GET /v1/licenses` |
| `request_license` | `POST /v1/license_requests` |
| `report_usage` | `POST /v1/usage_records` |
| `verify_receipt` | `POST /v1/verifications` |

The proposed interface has these ten tools. Each tool's arguments mirror the request body or parameters of
its endpoint. See [MCP tools](/api-reference/mcp/tools).

**The REST API** works when your orchestrator runs on your server. Call
[`POST /v1/checks`](/api-reference/checks/create-a-check) with your secret key from the
orchestrator, never from inside the model's context. Keys and OAuth tokens stay with the client
or the server; the model only ever sees the authorization token it has to pass on.

Pass `on_escalate: "deny"` from agents that act while a person waits. The agent gets `deny` with
`review_required` at once instead of an escalation it cannot wait for. An agent that can come back
to the conversation later can keep `hold`, and follows an `escalate` to its decision with
`get_check`.

## Give the tool an authorization argument

Add an `authorization` string to the generation tool's input schema, and say in its description
when the agent must fill it: whenever the request names or shows a real person, with the
`authorization.token` from the check, and with the same prompt that was checked. Include the
check's `generation_instructions` as another argument so the tool can add them to the model's
input. The [agent integration design](/quickstarts/agents) shows a complete tool definition.

A tool cannot rely on the agent to say whether a person is involved. Decide what the tool does
when no token arrives:

| Tool posture | Behavior without a token |
| - | - |
| Strict | Refuse every call that has no token |
| Matched | Match the prompt against the signed [name index](/api-reference/talent/download-the-name-index); refuse on a match, and refuse any call with a reference image or voice sample |

A matched tool lets indirect references through, such as "the runner from Ridgeline's spring
campaign", because only a check resolves them. Use strict if your tool must not run an unresolved
indirect reference.

## Verify in the tool

Verification is local: a signature check against the JWKS and a few comparisons. Reject the
call when any of these fails.

| Check | Reject when |
| - | - |
| Signature | The token is not signed by a key in `https://app.reflections.ai/.well-known/jwks.json` |
| `typ` | It is not `tlp-auth+jwt` |
| `iss` | It is not `https://app.reflections.ai` |
| `aud` | It is not the Reflections account of the caller you are serving |
| `exp`, `iat` | `exp` has passed, or `iat` is in the future, allowing at most 60 seconds of clock leeway |
| `tlp.ver` | Its major version is not `1` |
| `tlp.execution.model` | It is not the model about to run |
| Count | You have already run `tlp.max_generations` generations for this `jti` |
| `tlp.obligations` | It lists a type your tool does not handle |

Count generations in a store that every instance of your tool shares, keyed by `jti` and kept
until 60 seconds after `exp`. An in-memory counter lets a token be reused once per instance.

If your tool serves many callers, each one registers its Reflections account ID with you, and you
accept a token only when `aud` is the account of the caller making the request. A token issued to
another platform fails here, which is what stops a token copied out of one conversation from
working somewhere else.

Cache the JWKS for its `Cache-Control` max-age, and refetch it at most once per max-age when a
token names an unknown `kid`. New keys are published 30 days before they sign anything, and a
`kid` is never reused.
The [agent integration design](/quickstarts/agents) has verification code for `jose` and `PyJWT`, and
[Authorization token](/api-reference/formats/authorization-token) lists every claim.

When verification fails, return a tool error with `isError: true` and a message that names the
failed check, so the agent can run `check_use` again. Do not log the token.

## After the tool generates

Nothing reaches a person before its generation is `allow`. Two arrangements meet that rule:

* **The tool submits.** The tool holds the bytes, so it calls
  [`POST /v1/generations`](/api-reference/generations/create-a-generation) itself, with the token's
  `jti` as `check`. It returns the output to the agent only on `allow`, with `c2pa` embedded in its
  C2PA manifest and the disclosure text.
* **The agent submits.** The tool returns a private reference to the output, with its `sha256`.
  The agent calls `submit_generation` and shows the output only on `allow`.

The first keeps enforcement inside the tool and is the safer default. Video and held outputs are
decided later: `submit_generation` returns `status: "checking"` or `"held"`, and the decision
reaches your platform as a `generation.*` webhook. An agent can also read it with
`get_generation`. Have the tool return a pending result, tell the user, and deliver when the
decision arrives.

## Licenses, usage and receipts from an agent

An agent acting for a licensee can answer a `deny` that carries a `license_request` or
`license_change` remedy with `request_license`, passing the denied check's ID as `check`. The
request asks; only a signature on the talent's side makes a license or a new revision, and a person
on the licensee's side accepts it at `acceptance_url`. No tool can sign or accept one.
When a check carries a `usage_report` obligation, report with `report_usage`. Any agent can
confirm a receipt with `verify_receipt`.

## Caching and revocation

Authorization tokens expire at most 15 minutes after they are issued, a revocation stops new
checks at once, and an output submitted under a revoked license is denied at the generation. A
tool that verifies each token and caches nothing else needs no revocation handling of its own. If your tool or orchestrator caches decisions, for example to reuse a check
across turns, read [`GET /v1/revocations`](/api-reference/revocations/list-revocations) with
`after` at least every 60 seconds and drop what it names. See
[Caching and outages](/build/caching-and-outages).

## What can go wrong

| Problem | Cause | What to do |
| - | - | - |
| Every token fails `aud` | The tool compares `aud` with its own account instead of the caller's | Map each caller to its Reflections account ID |
| Tokens fail after an hour of work | The agent reuses a token past `exp` | Run `check_use` again before each generation step |
| A token works twice on different instances | The count is kept in memory | Use a shared store keyed by `jti` |
| An unknown `kid` | Keys rotated and your JWKS cache is stale | Refetch the JWKS once, then reject |
| `409 generation_already_submitted` | Both the tool and the agent submitted the output | Choose one arrangement |

## Related

<Columns cols={2}>
  <Card title="Agent integration design" icon="robot" href="/quickstarts/agents">
    Review the proposed MCP flow and verify a token in your tool.
  </Card>

  <Card title="MCP overview" icon="plug" href="/api-reference/mcp/overview">
    Proposed OAuth, scopes and transport.
  </Card>

  <Card title="Model providers" icon="server" href="/guides/model-providers">
    The same verification at an inference API.
  </Card>

  <Card title="Tokens" icon="key" href="/standard/tokens">
    Token formats and verification rules in the Standard.
  </Card>
</Columns>


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