Planned Talent API integration guide. Mandates, review queues, license changes, revocations
and statements are not served through the current sandbox. The examples below are proposed API
workflows, not instructions for the current Talent Portal.
Start with the runnable quickstart and sandbox support matrix.
The mandate
The talent appoints you in the Talent Portal and chooses your powers. In live mode your account needs therepresent_talent capability, which Reflections adds when it approves the account. No
endpoint creates a mandate in this proposed contract. The current sandbox does not provide
mandates or the representative workflows below.
Your mandate is public. Every platform that reads the talent’s record sees your account, name,
role and powers in
representation, so a licensee knows who may sign. The talent can end the
mandate at any time; that is recorded as a revocation with scope: "mandate", and you receive
mandate.ended.
Set up
1
Create a restricted key
When these operations become available, restrict a key to the scopes
your systems use:
mandates:read, licenses:read, escalations:write,
license_requests:write, license_drafts:write, licenses:write, revocations:write,
statements:read, statements:write, and for audits usage:read and generations:read.
Webhook setup needs webhooks:manage. Give a review tool only escalations:write. See
Authentication.2
Subscribe to the talent-side events
Create a webhook endpoint for
escalation.created, license_request.created, license_draft.signed,
license_draft.declined, mandate.created and mandate.ended. Add the events of the
licenses you manage: license.accepted, license.declined, license.revised,
license.revision_declined, license.expired, revocation.created, revocation.overdue,
statement.issued and statement.disputed. An endpoint lists exact types, or ["*"] for
every type.3
Read your mandates
Talent-side calls take no
Reflections-Account header. The talent named in the call, and
your mandate for them, decide what you may do. A call your mandate does not cover fails with
403 mandate_required.Review escalations
Withreview_outputs, you decide checks that Reflections escalated to the talent’s side under
the talent’s customer licenses. escalation.created
tells you when one arrives, and GET /v1/escalations
is the queue, oldest deadline first.
Each escalation shows the request as the platform sent it, the use, the licensee, the platform,
and the term the question rests on:
review_url,
where they decide in the Talent Portal. decided_by names them; the talent’s audit record shows
the decision with your account and that name. A note of up to 500 characters
reaches the platform as escalation.note.
check.resolved and may generate.
An allow covers exactly the request that was escalated, bound by its request_digest; anything
different needs a new check. Decide before expires_at: 7 days, or the license’s shorter
escalation_window. An escalated check left unanswered becomes deny with hold_expired, and
resolving a decided or expired escalation returns 409 escalation_closed.
When a check invokes several talent, each talent’s side decides their own escalation, and
talent[].escalation names each one. The check is allowed only when every one allows; the first
deny decides it.
Escalations under platform licenses, such as a voice app’s license for its users’ personal use,
are reviewed by Reflections trust and safety, with a response target of one business day. They
do not appear in your queue.
Release held outputs
When a license’srelease_policy is per_output_review, every output waits for a person before
it can be delivered. Each held output is an escalation with reason: "release_review" and
subject.object: "generation". It carries the clean bytes at artifact.url, open for 15
minutes, and the findings Reflections recorded on them: which protected attributes held, which
of the talent’s rules held, and any rule marked unchecked because it could not be read.
Resolve it the same way. allow releases the output: the platform receives
generation.released and may deliver it with its
receipt. deny declines it: the platform receives
generation.denied with review_declined and must
never deliver it. A held output nobody releases by expires_at (7 days, or the license’s shorter
escalation_window) expires with review_expired. Until release, the platform may show its user
only a preview carrying the draft watermark.
Answer license requests
Withissue_licenses, you answer the requests licensees send the talent.
license_request.created tells you when one
arrives, and GET /v1/license_requests?talent=…&status=sent
lists the ones waiting. A request shows the use that prompted it when it came from a denied
check, the scope asked for, the offer and the licensee’s note.
To agree, draft a license that names the request. You may change any term: channels,
territories, dates, the appearance changes allowed, the talent’s rules (up to 160 characters
each), the release policy, the escalation window, which platforms may run checks, compensation,
and what happens to released outputs after a revocation (post_revocation).
scope holds only what you change from what the licensee asked for.
The draft returns the full terms the signer will see, the terms_digest its revision will carry
if it is signed as drafted, and signing_url. Change an open draft with
POST /v1/license_drafts/{draft_id}, or
discard it.
To refuse, decline the request with a
decision_note. The licensee receives it on
license_request.declined.
Sign
A draft grants nothing. A person signs it with a passkey atsigning_url, in the Talent Portal:
the talent when signer is talent, or a person at your account with issue_licenses when it is
representative. No endpoint signs a license.
The signing page shows every term, marked checked, which Reflections enforces, or recorded,
which is signed and shown but not enforced, such as exclusivity and conflicts. Rely on checked
terms for anything that must be enforced. See What we enforce. The
signer may change terms before signing.
When it is signed, you receive license_draft.signed
with license, license_revision and signed_as_drafted. A license a representative signs
records issued_by.party: "representative" with your account and mandate, and the revision’s
signatures lists the signer. If the signer declines, you receive
license_draft.declined.
The licensee then accepts on its hosted acceptance page. A new license is pending_acceptance
until it does, and you receive license.accepted. A new revision waits in the license’s
pending_revision, and the current revision stays in force until the licensee accepts it. You
receive license.revised when it does, or
license.revision_declined. To narrow a
license at once instead, suspend or revoke it.
Amendments and renewals are drafts too. Set kind to amend or renew, name the license, and
send only the terms that change, such as a new window for a renewal.
Suspend, resume and revoke
Withrevoke, you can narrow consent at once.
- Suspend a license during a dispute with
POST /v1/licenses/{license_id}/suspend. Checks deny withlicense_suspended, live sessions end, held outputs stay held, and you can resume it later. - Revoke a license with
POST /v1/revocations. New checks deny, pending and held work under the license is void, and live sessions end within seconds. Each platform that used it must stop generating, purge cached decisions, delete copies held at model providers and acknowledge byacknowledge_by, 24 hours later. - Revoke for cause after a breach, with
for_cause: trueand thecauseplatforms will read. Only then can a license’swithdrawpolicy require released outputs to be taken down. Platforms acknowledge the takedown separately, bypost_revocation.withdraw_by.
revocation.created.
Idempotency-Key and retry with the same key if you do not know whether it went through. The
response lists required_actions, acknowledge_by and what it cut in affected. Read each
platform’s acknowledgement, and any that is overdue, with
GET /v1/revocations?talent=….
Released outputs follow the license’s post_revocation term: retain, cease_distribution or,
for cause, withdraw. See Revocation.
Statements and audits
Withreceive_statements, you read each license’s monthly statement with
GET /v1/statements?talent=…: units reported by
platforms, units Reflections observed from checks and generations, the greater of the two billed,
and whether they reconciled. Reflections does not move money.
- When the licensee records a payment, confirm it arrived with
POST /v1/statements/{statement_id}/payments/{payment_id}/confirm. The statement becomespaidwhen confirmed payments reachamount_due. - If a statement is wrong, dispute it with the reason the licensee will read. It is reissued when the licensee’s usage records or payments change.
GET /v1/usage_records?talent=…
and GET /v1/generations?talent=… return every
usage record and every generation under the talent’s licenses: the platform, the licensee, the
decision, the findings and the receipt. On the talent’s audit request, Reflections can ask a
platform for its generation logs for a stated period. Receipts, usage records and statements are
kept for 7 years. Prompt text is kept only on deny and escalate, for 30 days.
Verify what you find
Receipts and verifications work with any key, or none at the public rate limit, so you can check a file you found that claims to be licensed:
Send an
invalid result, or a file that uses the talent with no receipt, to
Reflections support with the verification ID.
Current test coverage
The sandbox provides fictional licenses, checks, generations and an escalation-resolution helper. It does not provide mandates, a signing page, representative review queues, license acceptance helpers or a dashboard reset action. See the sandbox support matrix for supported tests and the quickstart for an executable path.Related
Parties
Talent, representatives, licensees, platforms and end users.
Escalation
Who reviews, how long it can take, and what expiry means.
Licenses
Revisions, digests and the terms a license can carry.
Revocation
What a revocation cuts, and what platforms must do.