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

# Planned MCP tools

> Proposed Talent API MCP tools: arguments, results, scopes and corresponding HTTP endpoints.

<Note>
  Planned protocol reference. These are proposed Talent API MCP tool definitions, not a tool
  list from a deployed server. The current sandbox is accessible over HTTP only.
  Start with the [runnable quickstart](/quickstart) and [sandbox support matrix](/sandbox).
</Note>

Each proposed tool calls one API endpoint as the account that connected. Its arguments are the endpoint's
request body (or query parameters), with the same names, types and limits, and its result is the
object the endpoint returns. The endpoint pages are the full reference for both.

The examples on this page illustrate test-mode responses, using Maya Okafor's fictional license
`lic_97bb8qgh1b9zk81anbjkmprxh4` (see [Sandbox](/sandbox)), so their objects have
`livemode: false`.

| Tool | Endpoint | Scope | Changes data |
| - | - | - | - |
| [`resolve_talent`](#resolve_talent) | `POST /v1/resolutions` | `talent:read` | No |
| [`check_use`](#check_use) | `POST /v1/checks` | `checks:write` | Yes |
| [`submit_generation`](#submit_generation) | `POST /v1/generations` | `generations:write` | Yes |
| [`get_check`](#get_check) | `GET /v1/checks/{check_id}` | `checks:write` | No |
| [`get_generation`](#get_generation) | `GET /v1/generations/{generation_id}` | `generations:write` | No |
| [`get_license`](#get_license) | `GET /v1/licenses/{license_id}` | `licenses:read` | No |
| [`list_licenses`](#list_licenses) | `GET /v1/licenses` | `licenses:read` | No |
| [`request_license`](#request_license) | `POST /v1/license_requests` | `license_requests:write` | Yes |
| [`report_usage`](#report_usage) | `POST /v1/usage_records` | `usage:write` | Yes |
| [`verify_receipt`](#verify_receipt) | `POST /v1/verifications` | None | No |

Every result is returned as structured content and as the same JSON in a text block. When the API
returns an error, the tool result has `isError: true` and holds the
[problem details](/api-reference/errors), with its `code`. A `deny` or `escalate` is not an error:
it is a normal result with a `decision`.

The four tools that change data take a required `idempotency_key`, which the server sends as the
endpoint's [`Idempotency-Key`](/api-reference/idempotency). Use a new value for each new use and
the same value when a client retries the call, so a retry returns the first result instead of
checking, submitting or reporting twice. Each tool's definition is the JSON that `tools/list`
returns, with its input schema and
[annotations](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool).

## resolve\_talent

Finds which talent a prompt, image or voice sample invokes. Calls
[Resolve talent](/api-reference/resolutions/resolve-talent). Scope `talent:read`.

| Argument | Type | |
| - | - | - |
| `inputs` | array of inputs | Required. 1 to 64, each with a `role` and `text`, or media as `url` with `sha256`. |
| `modality` | string | The modality to resolve for, such as `speech`. |
| `exclude_talent` | array of `tal_` IDs | Talent the user said they did not mean. |

```json theme={null}
{
  "inputs": [{ "role": "prompt", "text": "A podcast intro read by Maya Okafor" }],
  "modality": "speech"
}
```

Returns a resolution:

```json theme={null}
{
  "id": "res_0wxyhk5zba2q8v1m3n7p4r6s9t",
  "object": "resolution",
  "livemode": false,
  "status": "matched",
  "candidates": [
    {
      "talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
      "name": "Maya Okafor",
      "matched_by": "name",
      "confidence": "high",
      "licensed": true,
      "declaration": "license_required"
    }
  ],
  "use_kind": "impersonation"
}
```

`status: none` means no protected talent was found. It is not permission; `check_use` still decides.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `Resolution` object that `POST /v1/resolutions` returns.

  ```json theme={null}
  {
    "name": "resolve_talent",
    "title": "Resolve talent",
    "description": "Find which protected talent a prompt, image or voice sample names or shows, before you check a use. A result with no candidates is not permission: call check_use before generating any real person.",
    "inputSchema": {
      "type": "object",
      "required": ["inputs"],
      "properties": {
        "inputs": {
          "type": "array",
          "minItems": 1,
          "maxItems": 64,
          "items": {
            "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": {
                "type": "string",
                "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`.",
                "pattern": "^[0-9a-f]{64}$"
              },
              "media_type": {
                "type": "string",
                "description": "The MIME type of the media at `url`, or `text/plain` for a withheld text input."
              }
            }
          },
          "description": "The parts of the request, in order, as you would send them on a check."
        },
        "modality": {
          "type": "string",
          "description": "What the model will generate, as in a check's `use.modality`.",
          "enum": ["image", "video", "speech", "audio", "text"]
        },
        "exclude_talent": {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^tal_[0-9a-hjkmnp-tv-z]{26}$"
          },
          "description": "Talent your user confirmed they did not mean. They are left out of `candidates`."
        }
      }
    },
    "annotations": {
      "title": "Resolve talent",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## check\_use

Decides whether a use may proceed, before anything is generated. Calls
[Create a check](/api-reference/checks/create-a-check). Scope `checks:write`.

| Argument | Type | |
| - | - | - |
| `inputs` | array of inputs | Required. Everything the generation tool will receive: the prompt, system text, rewritten prompt and references. |
| `use` | object | Required. `modality`, `kind`, `purpose`, `commercial`, and `channels` and `territories` when commercial. |
| `talent` | array of `tal_` IDs | Talent your user picked. The inputs are still resolved for anyone else. |
| `exclude_talent` | array of `tal_` IDs | Talent the user confirmed they did not mean. |
| `facet` | `fct_` ID | A specific facet, such as one of several voices. |
| `license` | `lic_` ID | A specific license. By default the narrowest license that allows the use is chosen. |
| `end_user` | object | `id`, a stable ID for the person the agent acts for. Never an email or a name. |
| `execution` | object | `provider`, `model` and `candidates` of the generation tool. |
| `on_escalate` | string | `hold` (default) or `deny`. |
| `reuse` | object | `max_generations` (up to 1,000) and `ttl` (up to `PT15M`). |
| `prompt_handling` | object | `mode` and `retention`. |
| `metadata` | object | Your own keys. |
| `idempotency_key` | string | Required. Sent as the `Idempotency-Key`. Reuse it only when retrying this call. |

```json theme={null}
{
  "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"]
  },
  "end_user": { "id": "usr_48213" },
  "execution": { "provider": "example-image-provider", "model": "image-model-3", "candidates": 1 },
  "on_escalate": "deny",
  "idempotency_key": "a9bbbc20-9aeb-5252-a56d-983f8db19ea2"
}
```

Returns a check. The fields an agent acts on:

```json theme={null}
{
  "id": "chk_njtrx9ds0f6ttqpp538zqppeg7",
  "object": "check",
  "livemode": false,
  "status": "allowed",
  "decision": "allow",
  "reasons": [],
  "obligations": [
    { "type": "generation_check", "required": "all" },
    { "type": "generation_instructions", "instructions": ["Keep Maya Okafor the same person: face, skin tone and build unchanged."] },
    { "type": "disclosure", "level": "licensed", "placement": "both", "text": "Made with AI. Likeness used under license." },
    { "type": "c2pa_manifest" }
  ],
  "authorization": {
    "token": "eyJhbGciOiJFUzI1NiIs…",
    "max_generations": 1,
    "generations_used": 0,
    "expires_at": "2026-10-17T18:15:00Z"
  },
  "remedy": null
}
```

On `allow`, pass `authorization.token` to the generation tool with the same inputs, and add every
`generation_instructions` entry to what it receives. On `deny`, show `reasons[].sentence`; if
`remedy.type` is `license_request` or `license_change`, offer `request_license`. On `escalate`,
tell the user the request is with the talent's reviewer, and read the outcome later with
[`get_check`](#get_check). An agent that cannot come back to a conversation passes
`on_escalate: "deny"`.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `Check` object that `POST /v1/checks` returns.

  ```json theme={null}
  {
    "name": "check_use",
    "title": "Check a use",
    "description": "Decide whether a use of a real person's name, likeness or voice may proceed, before you generate anything. Send everything the generation tool will receive. On allow, pass authorization.token to the generation tool and follow every obligation. On deny, show reasons[].sentence to the user and do not generate. On escalate, do not generate yet; read the decision later with get_check.",
    "inputSchema": {
      "type": "object",
      "required": ["inputs", "use", "idempotency_key"],
      "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": {
            "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": {
                "type": "string",
                "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`.",
                "pattern": "^[0-9a-f]{64}$"
              },
              "media_type": {
                "type": "string",
                "description": "The MIME type of the media at `url`, or `text/plain` for a withheld text input."
              }
            }
          },
          "description": "Everything the model will receive, in order: the user's prompt, your system text, any rewritten prompt, references and conversation history."
        },
        "use": {
          "type": "object",
          "required": ["modality", "kind", "purpose", "commercial"],
          "properties": {
            "modality": {
              "type": "string",
              "description": "What will be generated.",
              "enum": ["image", "video", "speech", "audio", "text"]
            },
            "kind": {
              "type": "string",
              "description": "How the talent appears in the output.",
              "enum": ["depiction", "impersonation", "endorsement", "reference"]
            },
            "purpose": {
              "type": "string",
              "enum": [
                "advertising",
                "branded_content",
                "entertainment",
                "editorial",
                "personal",
                "education",
                "political"
              ],
              "description": "What the output is for."
            },
            "commercial": {
              "type": "boolean",
              "description": "Whether anyone earns money from the output, including through advertising."
            },
            "channels": {
              "type": "array",
              "items": {
                "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"
                ]
              },
              "maxItems": 20,
              "description": "Required when `commercial` is true."
            },
            "territories": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "An ISO 3166-1 alpha-2 country code, or `WW` for worldwide.",
                "pattern": "^([A-Z]{2})$"
              },
              "maxItems": 50,
              "description": "Required when `commercial` is true."
            }
          },
          "description": "How the output will be used. A different use needs a new check."
        },
        "end_user": {
          "type": "object",
          "description": "The person the request is for. Send it on every check made for a person.",
          "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": "The model that will run the request and how many outputs it will make. `provider` and `model` are part of `request_digest`.",
          "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."
            }
          }
        },
        "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": [
                {
                  "type": "string",
                  "description": "An ISO 8601 duration, such as `PT60S` or `P30D`."
                }
              ],
              "description": "How long the window lasts. At most `PT15M`."
            }
          }
        },
        "prompt_handling": {
          "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`."
            }
          },
          "description": "How text inputs reach Reflections: `full` by default, `redacted` or `withheld`."
        },
        "metadata": {
          "type": "object",
          "description": "Your own keys, returned on the check.",
          "additionalProperties": {
            "type": "string",
            "maxLength": 500
          },
          "maxProperties": 50
        },
        "idempotency_key": {
          "type": "string",
          "maxLength": 255,
          "description": "Sent as the Idempotency-Key. Use a new value for each new use, and the same value when you retry this call: a retry then returns the first result instead of running twice."
        }
      }
    },
    "annotations": {
      "title": "Check a use",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## submit\_generation

Checks an output before anyone sees it. Calls
[Create a generation](/api-reference/generations/create-a-generation). Scope `generations:write`.

| Argument | Type | |
| - | - | - |
| `check` | `chk_` ID | The check the output was made under. Required unless `session` is set. |
| `session` | `ses_` ID | The session the output was made in, instead of a `check`. |
| `candidate_index` | integer | Which of the check's candidates this is, from 0. Omit under `reuse`. |
| `artifact` | object | Proposed output contract: `url` or base64 `data` (10 MB target), with `sha256` (required), `media_type` and `duration_ms`. The current HTTP sandbox accepts at most 7 MiB decoded bytes in a 10 MiB JSON body and does not fetch URLs. |
| `execution` | object | `provider`, `model` and `job_id`. |
| `transcript` | string | Words spoken in the output, if you have them. |
| `watermark` | object | `algorithm` and `id` of a watermark you applied. |
| `metadata` | object | Your own keys. |
| `idempotency_key` | string | Required. Sent as the `Idempotency-Key`. Reuse it only when retrying this call. |

```json theme={null}
{
  "check": "chk_njtrx9ds0f6ttqpp538zqppeg7",
  "candidate_index": 0,
  "artifact": {
    "url": "https://cdn.northlight.example/outputs/88213.png",
    "sha256": "9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a",
    "media_type": "image/png"
  },
  "execution": { "provider": "example-image-provider", "model": "image-model-3", "job_id": "job_88213" },
  "idempotency_key": "1225df77-5ee5-5bff-8b55-cf555e6c6bee"
}
```

Returns a generation:

```json theme={null}
{
  "id": "gen_ekqjdddns0qtrqjb6vt85722ky",
  "object": "generation",
  "livemode": false,
  "status": "allowed",
  "decision": "allow",
  "assurance": "observed",
  "receipt": "rcpt_e3g0e4fx2nzv12c20b2tkyj9xq",
  "c2pa": {
    "label": "ai.reflections.license",
    "data": {
      "receipt": "eyJhbGciOiJFUzI1NiIs…",
      "verify_url": "https://app.reflections.ai/r/rcpt_e3g0e4fx2nzv12c20b2tkyj9xq"
    }
  }
}
```

Deliver the output only when `decision` is `allow`, after you embed `c2pa` as described in
[C2PA assertion](/api-reference/formats/c2pa-assertion). Video and longer audio return
`status: "checking"`; read the decision with [`get_generation`](#get_generation), or receive it as
a [webhook](/api-reference/webhooks/overview) to your platform.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `Generation` object that `POST /v1/generations` returns.

  ```json theme={null}
  {
    "name": "submit_generation",
    "title": "Submit an output",
    "description": "Submit an output made under an allowed check or session, before anyone sees it. Release the output only when the result's decision is allow, and embed the receipt it returns.",
    "inputSchema": {
      "type": "object",
      "required": ["artifact", "idempotency_key"],
      "oneOf": [
        {
          "required": ["check"]
        },
        {
          "required": ["session"]
        }
      ],
      "properties": {
        "check": {
          "type": "string",
          "pattern": "^chk_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "The check this output was made under. Required unless `session` is set."
        },
        "session": {
          "type": "string",
          "pattern": "^ses_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "The session this output was made in, instead of a `check`."
        },
        "candidate_index": {
          "type": "integer",
          "minimum": 0,
          "maximum": 15,
          "description": "Which of the check's `execution.candidates` this is, from 0. Omit under `reuse`."
        },
        "artifact": {
          "type": "object",
          "description": "The output's bytes, as a file ID, a URL or base64 `data`, with their SHA-256.",
          "required": ["sha256"],
          "properties": {
            "file": {
              "type": "string",
              "pattern": "^file_[0-9a-hjkmnp-tv-z]{26}$",
              "description": "A file uploaded with `purpose=output`."
            },
            "url": {
              "type": "string",
              "format": "uri",
              "description": "A URL Reflections can fetch the bytes from."
            },
            "data": {
              "type": "string",
              "description": "Base64 bytes. Sandbox limit: 7 MiB decoded (7,340,032 bytes); total JSON request limit: 10 MiB.",
              "contentEncoding": "base64"
            },
            "sha256": {
              "type": "string",
              "description": "The SHA-256 of the bytes. If the bytes Reflections receives differ, the call fails with `422 artifact_digest_mismatch`.",
              "pattern": "^[0-9a-f]{64}$"
            },
            "media_type": {
              "type": "string",
              "description": "The bytes' media type, such as `image/png`."
            },
            "duration_ms": {
              "type": "integer",
              "minimum": 0,
              "description": "For audio and video."
            }
          }
        },
        "execution": {
          "type": "object",
          "description": "The run that made the output. Send `job_id` when the provider gives one.",
          "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."
            }
          }
        },
        "transcript": {
          "type": "string",
          "maxLength": 32000,
          "description": "Words spoken in the output, if you have them. Reflections transcribes regardless."
        },
        "watermark": {
          "type": "object",
          "description": "A watermark you applied, so verification can join it to this generation.",
          "properties": {
            "algorithm": {
              "type": "string",
              "description": "The watermarking method you used."
            },
            "id": {
              "type": "string",
              "description": "The watermark's identifier, as embedded in the output."
            }
          }
        },
        "c2pa_signer": {
          "type": "object",
          "required": ["thumbprint"],
          "additionalProperties": false,
          "properties": {
            "thumbprint": {
              "type": "string",
              "pattern": "^sha256:[0-9a-f]{64}$",
              "description": "`sha256:` and the lowercase hex SHA-256 of the DER encoding of the certificate that signs the C2PA claim, the end-entity certificate in the manifest's signature."
            }
          },
          "description": "The certificate that will sign the output's C2PA claim. The receipt signs its thumbprint as `tlp.c2pa_signer`, as given; Reflections does not check it against a certificate. A verifier that checks the manifest can then reject the assertion in a manifest another certificate signed. Without it, the receipt is evidence of a decision, not of a particular file."
        },
        "metadata": {
          "type": "object",
          "description": "Your own keys, returned on the generation.",
          "additionalProperties": {
            "type": "string",
            "maxLength": 500
          },
          "maxProperties": 50
        },
        "idempotency_key": {
          "type": "string",
          "maxLength": 255,
          "description": "Sent as the Idempotency-Key. Use a new value for each new use, and the same value when you retry this call: a retry then returns the first result instead of running twice."
        }
      }
    },
    "annotations": {
      "title": "Submit an output",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## get\_check

Reads a check, to follow an escalation to its decision. Calls
[Retrieve a check](/api-reference/checks/retrieve-a-check). Scope `checks:write`.

| Argument | Type | |
| - | - | - |
| `check_id` | `chk_` ID | Required. |

```json theme={null}
{ "check_id": "chk_njtrx9ds0f6ttqpp538zqppeg7" }
```

Returns the check. While a reviewer has it, `status` is `escalated` and `escalation.expires_at`
says when it becomes a `deny`. Once decided, `decision` is `allow` with an `authorization`, or
`deny` with `reasons`. Read it at most once every 5 seconds; a reviewer usually answers in hours,
not seconds, so a longer interval is better.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `Check` object that `GET /v1/checks/{check_id}` returns.

  ```json theme={null}
  {
    "name": "get_check",
    "title": "Get a check",
    "description": "Read a check, to learn the decision on an escalated check. Call it at most once every 5 seconds.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "check_id": {
          "type": "string",
          "pattern": "^chk_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "The check's ID."
        }
      },
      "required": ["check_id"]
    },
    "annotations": {
      "title": "Get a check",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## get\_generation

Reads a generation, to collect the decision on a video, longer audio or a held output. Calls
[Retrieve a generation](/api-reference/generations/retrieve-a-generation). Scope
`generations:write`.

| Argument | Type | |
| - | - | - |
| `generation_id` | `gen_` ID | Required. |

```json theme={null}
{ "generation_id": "gen_ekqjdddns0qtrqjb6vt85722ky" }
```

Returns the generation. `status` moves from `checking` or `held` to `allowed`, `released` or
`denied`. Deliver on `allowed` or `released` only, with the `c2pa` assertion embedded.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `Generation` object that `GET /v1/generations/{generation_id}` returns.

  ```json theme={null}
  {
    "name": "get_generation",
    "title": "Get a generation",
    "description": "Read a generation, to collect the decision on a held output, a video or longer audio. Call it at most once every 5 seconds.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "generation_id": {
          "type": "string",
          "pattern": "^gen_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "The generation's ID."
        }
      },
      "required": ["generation_id"]
    },
    "annotations": {
      "title": "Get a generation",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## get\_license

Reads one license. Calls [Retrieve a license](/api-reference/licenses/retrieve-a-license). Scope
`licenses:read`.

| Argument | Type | |
| - | - | - |
| `license_id` | `lic_` ID | Required. |

```json theme={null}
{ "license_id": "lic_97bb8qgh1b9zk81anbjkmprxh4" }
```

Returns a license, with its `status`, `handle`, `current_revision`, `terms_digest` and normalized
`scope`:

```json theme={null}
{
  "id": "lic_97bb8qgh1b9zk81anbjkmprxh4",
  "object": "license",
  "livemode": false,
  "status": "active",
  "handle": "T8M3QX",
  "talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
  "licensee": "acct_7p4r6s9t0wxyhk5zba2q8v1m3n",
  "current_revision": "lrv_11knr0923nvdw36qe404d6c55d",
  "revision_number": 1,
  "terms_digest": "sha256:4036ac3ffc579dc70d5a9132242e3cb588007d08bee1b2b92812b2d4e3ff7f4e",
  "scope": {
    "modalities": ["image", "video", "speech"],
    "purposes": ["advertising"],
    "commercial": true,
    "channels": ["social", "web"],
    "territories": ["US", "CA"]
  }
}
```

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `License` object that `GET /v1/licenses/{license_id}` returns.

  ```json theme={null}
  {
    "name": "get_license",
    "title": "Get a license",
    "description": "Read one license: its scope, terms, window and status.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "license_id": {
          "type": "string",
          "pattern": "^lic_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "The license's ID."
        }
      },
      "required": ["license_id"]
    },
    "annotations": {
      "title": "Get a license",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## list\_licenses

Lists the licenses the account holds or may use. Calls
[List licenses](/api-reference/licenses/list-licenses). Scope `licenses:read`.

| Argument | Type | |
| - | - | - |
| `talent` | `tal_` ID | Only licenses for this talent. |
| `status` | string | Only licenses with this status, such as `active`. |
| `limit` | integer | 1 to 100. Default 20. |
| `cursor` | string | The `next_cursor` from the previous result. |

```json theme={null}
{ "talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s", "status": "active" }
```

Returns a [list](/api-reference/pagination) of licenses: `data`, `has_more` and `next_cursor`.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `LicenseList` object that `GET /v1/licenses` returns.

  ```json theme={null}
  {
    "name": "list_licenses",
    "title": "List licenses",
    "description": "List the licenses the account holds or may use, optionally for one talent.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "role": {
          "type": "string",
          "enum": ["licensee", "issuer"],
          "default": "licensee",
          "description": "`licensee` (the default): licenses you hold. `issuer`: licenses you issued as talent."
        },
        "talent": {
          "type": "string",
          "pattern": "^tal_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "Only licenses granted by this talent."
        },
        "status": {
          "type": "string",
          "description": "Only licenses with this status, such as `active`. Live reads also accept `void`; the sandbox status filter does not.",
          "enum": [
            "pending_acceptance",
            "scheduled",
            "active",
            "suspended",
            "expired",
            "declined",
            "revoked",
            "void"
          ]
        },
        "limit": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20,
          "description": "Number of objects to return, 1 to 100."
        },
        "cursor": {
          "type": "string",
          "description": "The `next_cursor` from the previous page."
        }
      }
    },
    "annotations": {
      "title": "List licenses",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## request\_license

Asks a talent for a new license, or a wider one. Calls
[Request a license](/api-reference/license-requests/request-a-license). Scope
`license_requests:write`.

| Argument | Type | |
| - | - | - |
| `kind` | string | Required. `new` or `change`. |
| `talent` | `tal_` ID | Required. |
| `requested_scope` | object | Required. The scope you ask for: facets, modalities, purposes, channels, territories, dates and more. |
| `license` | `lic_` ID | Required for `change`. |
| `check` | `chk_` ID | The denied check this request answers. The talent sees the use that prompted it. |
| `offer` | object | What you offer to pay, as compensation. |
| `note` | string | Shown to the talent as written, up to 2,000 characters. |
| `metadata` | object | Your own keys. |
| `idempotency_key` | string | Required. Sent as the `Idempotency-Key`. Reuse it only when retrying this call. |

```json theme={null}
{
  "kind": "change",
  "talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
  "license": "lic_97bb8qgh1b9zk81anbjkmprxh4",
  "check": "chk_pmx6dzq8fwbhtagr03q59ehs40",
  "requested_scope": { "channels": ["social", "web", "tv"] },
  "note": "We would like to run the spring trail images as a TV spot in the US and Canada.",
  "idempotency_key": "f4aced76-7a7e-5d3d-8202-2dea9eb75075"
}
```

Returns a license request with `status: "sent"`:

```json theme={null}
{
  "id": "lrq_t0wxyhk5zba2q8v1m3n7p4r6s9",
  "object": "license_request",
  "livemode": false,
  "kind": "change",
  "status": "sent",
  "talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
  "license": "lic_97bb8qgh1b9zk81anbjkmprxh4",
  "check": "chk_pmx6dzq8fwbhtagr03q59ehs40"
}
```

A request changes nothing by itself. The talent or their representative answers it, and may change
any term; only their signature makes a license or a new revision. The licensee then accepts it at
the license's `acceptance_url`, where a person on the licensee's side signs. No tool can sign or
accept a license.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `LicenseRequest` object that `POST /v1/license_requests` returns.

  ```json theme={null}
  {
    "name": "request_license",
    "title": "Request a license",
    "description": "Ask a talent for a new license, or a change to one, when a check was denied with a license_request or license_change remedy. The talent's side decides; nothing is granted by this call.",
    "inputSchema": {
      "type": "object",
      "required": ["kind", "talent", "requested_scope", "idempotency_key"],
      "properties": {
        "kind": {
          "type": "string",
          "enum": ["new", "change"],
          "description": "`new` for a new license, or `change` for a new revision of the license in `license`, such as a wider scope."
        },
        "talent": {
          "type": "string",
          "pattern": "^tal_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "The talent to ask. A talent whose `posture.accepts_requests` is `false` takes no requests through the API."
        },
        "license": {
          "type": "string",
          "pattern": "^lic_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "Required for `change`."
        },
        "check": {
          "type": "string",
          "pattern": "^chk_[0-9a-hjkmnp-tv-z]{26}$",
          "description": "The denied check this request answers. The talent sees the use that prompted it."
        },
        "requested_scope": {
          "type": "object",
          "description": "The terms you ask for. A denied check's `remedy.suggested_scope` is a starting point. For `change`, omitted fields keep the current license's terms.",
          "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": {
                "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"]
              },
              "description": "The facet types you ask for, such as `likeness`, when you do not name `facets`."
            },
            "modalities": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "What will be generated. `speech` is a voice speaking words; `audio` is any other sound.",
                "enum": ["image", "video", "speech", "audio", "text"]
              },
              "description": "What you want to generate."
            },
            "kinds": {
              "type": "array",
              "items": {
                "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"]
              },
              "description": "How the talent would appear."
            },
            "purposes": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "advertising",
                  "branded_content",
                  "entertainment",
                  "editorial",
                  "personal",
                  "education",
                  "political"
                ]
              },
              "description": "What the outputs are for."
            },
            "commercial": {
              "type": "boolean",
              "description": "`true` to ask for commercial use."
            },
            "channels": {
              "type": "array",
              "items": {
                "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"
                ]
              },
              "description": "Where outputs would appear. For `change`, list every channel you want, not only the new ones."
            },
            "territories": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "An ISO 3166-1 alpha-2 country code, or `WW` for worldwide.",
                "pattern": "^([A-Z]{2})$"
              },
              "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": {
                "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"
                ]
              }
            },
            "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."
            }
          }
        },
        "offer": {
          "type": "object",
          "description": "What you offer to pay. The talent's side may sign different compensation.",
          "required": ["type"],
          "properties": {
            "type": {
              "type": "string",
              "enum": ["none", "flat", "per_unit", "revenue_share"],
              "description": "How the amount owed is set: `none` owes nothing, `flat` is a fixed fee, `per_unit` is a rate per unit of usage, and `revenue_share` is `revenue_share_bps` of revenue."
            },
            "flat": {
              "type": "object",
              "required": ["amount", "currency"],
              "properties": {
                "amount": {
                  "type": "integer",
                  "description": "In the currency's smallest unit, such as cents."
                },
                "currency": {
                  "type": "string",
                  "pattern": "^[a-z]{3}$",
                  "description": "ISO 4217, lowercase."
                }
              },
              "description": "The fixed fee, for `type: flat`."
            },
            "per_unit": {
              "type": "object",
              "description": "The rate, for `type: per_unit`.",
              "properties": {
                "units": {
                  "type": "string",
                  "enum": ["outputs", "seconds", "characters", "placements", "impressions"],
                  "description": "What the rate counts. Reflections observes outputs, seconds and characters itself; placements and impressions come from usage you report."
                },
                "rate": {
                  "type": "object",
                  "required": ["amount", "currency"],
                  "properties": {
                    "amount": {
                      "type": "integer",
                      "description": "In the currency's smallest unit, such as cents."
                    },
                    "currency": {
                      "type": "string",
                      "pattern": "^[a-z]{3}$",
                      "description": "ISO 4217, lowercase."
                    }
                  },
                  "description": "The amount owed for each `per` units."
                },
                "per": {
                  "type": "integer",
                  "default": 1,
                  "description": "The rate is for this many units, such as 1000 impressions."
                }
              }
            },
            "revenue_share_bps": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000,
              "description": "Basis points of revenue the license names."
            },
            "minimum": {
              "type": "object",
              "required": ["amount", "currency"],
              "properties": {
                "amount": {
                  "type": "integer",
                  "description": "In the currency's smallest unit, such as cents."
                },
                "currency": {
                  "type": "string",
                  "pattern": "^[a-z]{3}$",
                  "description": "ISO 4217, lowercase."
                }
              },
              "description": "The least the licensee owes, however little is used."
            },
            "schedule": {
              "type": "string",
              "enum": ["on_acceptance", "monthly", "quarterly"],
              "description": "When the licensee pays: once on acceptance, each month, or each quarter."
            }
          }
        },
        "note": {
          "type": "string",
          "maxLength": 2000,
          "description": "Shown to the talent as written."
        },
        "metadata": {
          "type": "object",
          "description": "Your own key-value pairs, returned on the request.",
          "additionalProperties": {
            "type": "string",
            "maxLength": 500
          },
          "maxProperties": 50
        },
        "idempotency_key": {
          "type": "string",
          "maxLength": 255,
          "description": "Sent as the Idempotency-Key. Use a new value for each new use, and the same value when you retry this call: a retry then returns the first result instead of running twice."
        }
      }
    },
    "annotations": {
      "title": "Request a license",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## report\_usage

Reports usage for generations and sessions. Calls
[Report usage](/api-reference/usage-records/report-usage). Scope `usage:write`.

| Argument | Type | |
| - | - | - |
| `records` | array | Required. 1 to 1,000 records. |
| `records[].subject` | `gen_` or `ses_` ID | Required. What the record settles. |
| `records[].units` | string | Required. `outputs`, `seconds`, `characters`, `placements` or `impressions`. |
| `records[].quantity` | number | Required. |
| `records[].occurred_at` | timestamp | Required. |
| `records[].placement` | object | `channel`, `territory` and `url`, for `placements` and `impressions`. |
| `records[].correction_of` | `ur_` ID | The record this one replaces. |
| `idempotency_key` | string | Required. Sent as the `Idempotency-Key`. Reuse it only when retrying this call. |

```json theme={null}
{
  "records": [
    {
      "subject": "gen_ekqjdddns0qtrqjb6vt85722ky",
      "units": "placements",
      "quantity": 1,
      "occurred_at": "2026-10-18T09:00:00Z",
      "placement": { "channel": "social", "territory": "US" }
    }
  ],
  "idempotency_key": "1d0e4ed6-3f36-5fa6-bd39-91d188e6e7f2"
}
```

Returns a list of usage records, each `accepted` or `rejected` with a `rejection.code`.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `UsageRecordList` object that `POST /v1/usage_records` returns.

  ```json theme={null}
  {
    "name": "report_usage",
    "title": "Report usage",
    "description": "Report how outputs and sessions were used, as the license's usage_report obligation requires.",
    "inputSchema": {
      "type": "object",
      "required": ["records", "idempotency_key"],
      "properties": {
        "records": {
          "type": "array",
          "minItems": 1,
          "maxItems": 1000,
          "items": {
            "type": "object",
            "required": ["subject", "units", "quantity", "occurred_at"],
            "properties": {
              "subject": {
                "type": "string",
                "pattern": "^(gen|ses)_[0-9a-hjkmnp-tv-z]{26}$",
                "description": "The generation or session this record settles."
              },
              "license": {
                "type": "string",
                "pattern": "^lic_[0-9a-hjkmnp-tv-z]{26}$",
                "description": "The license the usage counts against. Required when the subject was decided under more than one license; send one record per license."
              },
              "units": {
                "type": "string",
                "enum": ["outputs", "seconds", "characters", "placements", "impressions"],
                "description": "The unit `quantity` counts. Report the `units` the `usage_report` obligation names."
              },
              "quantity": {
                "type": "number",
                "minimum": 0,
                "description": "How many `units`. May be fractional, such as `3.4` seconds."
              },
              "occurred_at": {
                "type": "string",
                "format": "date-time",
                "description": "When the use happened."
              },
              "placement": {
                "type": "object",
                "description": "For `placements` and `impressions`.",
                "properties": {
                  "channel": {
                    "type": "string",
                    "description": "Where the output was placed.",
                    "enum": [
                      "social",
                      "web",
                      "in_app",
                      "streaming",
                      "tv",
                      "cinema",
                      "out_of_home",
                      "print",
                      "audio",
                      "email",
                      "retail",
                      "games",
                      "private"
                    ]
                  },
                  "territory": {
                    "type": "string",
                    "description": "The country where the output was placed or shown.",
                    "pattern": "^([A-Z]{2})$"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "The placement's address, when it has one."
                  }
                }
              },
              "correction_of": {
                "type": "string",
                "pattern": "^ur_[0-9a-hjkmnp-tv-z]{26}$",
                "description": "The record this one replaces."
              },
              "metadata": {
                "type": "object",
                "description": "Your own keys, such as your batch ID. Returned on the record.",
                "additionalProperties": {
                  "type": "string",
                  "maxLength": 500
                },
                "maxProperties": 50
              }
            }
          },
          "description": "1 to 1,000 records. Each is accepted or rejected on its own."
        },
        "idempotency_key": {
          "type": "string",
          "maxLength": 255,
          "description": "Sent as the Idempotency-Key. Use a new value for each new use, and the same value when you retry this call: a retry then returns the first result instead of running twice."
        }
      }
    },
    "annotations": {
      "title": "Report usage",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## verify\_receipt

Verifies a receipt, a manifest or a file, and returns the receipt it matches with its live status.
Calls [Verify content](/api-reference/verifications/verify-content). No scope is needed.

Send exactly one argument:

| Argument | Type | |
| - | - | - |
| `receipt` | string | A receipt ID or JWS. |
| `manifest` | string | A C2PA manifest store, base64. |
| `url` | string | A file Reflections can fetch. |
| `sha256` | string | The hex SHA-256 of a file. |
| `fingerprint` | object | A perceptual hash and embeddings. |

```json theme={null}
{ "receipt": "rcpt_e3g0e4fx2nzv12c20b2tkyj9xq" }
```

Returns a verification:

```json theme={null}
{
  "id": "vrf_gf41f2za3zh7vv50jyheky90mc",
  "object": "verification",
  "result": "verified",
  "method": "receipt",
  "receipt": {
    "id": "rcpt_e3g0e4fx2nzv12c20b2tkyj9xq",
    "livemode": false,
    "decision": "allow",
    "assurance": "observed",
    "use_status": "permitted"
  }
}
```

`result: "not_found"` says nothing about whether the content is licensed. `invalid` means a
receipt or manifest is present and fails verification.

<Accordion title="Tool definition">
  As `tools/list` returns it. Its `outputSchema` is the JSON Schema of the `Verification` object that `POST /v1/verifications` returns.

  ```json theme={null}
  {
    "name": "verify_receipt",
    "title": "Verify a receipt",
    "description": "Verify a receipt, a C2PA manifest or a file, and read the receipt it matches with its live use status. A not_found result says nothing about whether the content is licensed.",
    "inputSchema": {
      "type": "object",
      "description": "Send exactly one of `receipt`, `manifest`, `url`, `sha256` or `fingerprint`.",
      "properties": {
        "receipt": {
          "type": "string",
          "description": "A receipt ID or JWS."
        },
        "manifest": {
          "type": "string",
          "contentEncoding": "base64",
          "description": "A C2PA manifest store."
        },
        "url": {
          "type": "string",
          "format": "uri",
          "description": "A file Reflections can fetch."
        },
        "sha256": {
          "type": "string",
          "description": "SHA-256 of the file's bytes, in hex. Matches only an exact copy of a registered output.",
          "pattern": "^[0-9a-f]{64}$"
        },
        "fingerprint": {
          "type": "object",
          "description": "A fingerprint you computed, when the bytes cannot leave your platform.",
          "properties": {
            "perceptual_hash": {
              "type": "object",
              "description": "A perceptual hash of the file.",
              "required": ["algorithm", "value"],
              "properties": {
                "algorithm": {
                  "type": "string",
                  "enum": ["pdq", "vpdq", "chromaprint"],
                  "description": "`pdq` for images, `vpdq` for video, `chromaprint` for audio."
                },
                "value": {
                  "type": "string",
                  "description": "The hash in the algorithm's standard text form, such as 64 hex characters for `pdq`."
                }
              }
            },
            "embeddings": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["model", "vector"],
                "properties": {
                  "model": {
                    "type": "string",
                    "enum": ["reflections-face-1", "reflections-voice-1"],
                    "description": "The model that computed `vector`: `reflections-face-1` for faces, `reflections-voice-1` for voices."
                  },
                  "vector": {
                    "type": "string",
                    "contentEncoding": "base64",
                    "description": "Little-endian float32 values."
                  }
                }
              },
              "description": "Optional face or voice embeddings of the file, used with the hash to look it up."
            }
          }
        }
      }
    },
    "annotations": {
      "title": "Verify a receipt",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    }
  }
  ```
</Accordion>

## Related

<Columns cols={2}>
  <Card title="MCP server" icon="robot" href="/api-reference/mcp/overview">
    Proposed transport, OAuth and scopes.
  </Card>

  <Card title="Agent integration design" icon="bolt" href="/quickstarts/agents">
    A check, a token and a generation tool, end to end.
  </Card>
</Columns>


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