: "${REFLECTIONS_KEY:?Set REFLECTIONS_KEY before running this example}"
curl --fail-with-body --max-time 30 'https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6' \
-H "Authorization: Bearer $REFLECTIONS_KEY" \
-H "Reflections-Version: 2026-10-15"import { env, exit } from "node:process";
const apiKey = env.REFLECTIONS_KEY;
if (!apiKey) throw new Error("Set REFLECTIONS_KEY before running this example");
const response = await fetch("https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6", {
method: "GET",
headers: {
Authorization: `Bearer ${apiKey}`,
"Reflections-Version": "2026-10-15",
},
signal: AbortSignal.timeout(30_000),
});
const responseBody = await response.text();
if (!response.ok) {
console.error(`HTTP ${response.status}: ${responseBody}`);
exit(1);
}
console.log(responseBody);
import os
from urllib.error import HTTPError
from urllib.request import Request, urlopen
apiKey = os.environ["REFLECTIONS_KEY"]
if not apiKey:
raise ValueError("Set REFLECTIONS_KEY before running this example")
headers = {
"Authorization": f"Bearer {apiKey}",
"Reflections-Version": "2026-10-15",
}
request = Request("https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6",
method="GET", headers=headers)
try:
with urlopen(request, timeout=30) as response:
print(response.read().decode("utf-8"))
except HTTPError as error:
error_body = error.read().decode("utf-8")
raise RuntimeError(f"HTTP {error.code}: {error_body}") from error
package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
apiKey := os.Getenv("REFLECTIONS_KEY")
if apiKey == "" {
panic("Set REFLECTIONS_KEY before running this example")
}
request, err := http.NewRequest("GET", "https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6", nil)
if err != nil {
panic(err)
}
request.Header.Set("Authorization", "Bearer " + apiKey)
request.Header.Set("Reflections-Version", "2026-10-15")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil {
panic(err)
}
defer response.Body.Close()
responseBody, err := io.ReadAll(response.Body)
if err != nil {
panic(err)
}
if response.StatusCode < 200 || response.StatusCode >= 300 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, responseBody))
}
fmt.Print(string(responseBody))
}
{
"id": "rvk_s9t0wxyhk5zba2q8v1m3n7p4r6",
"object": "revocation",
"livemode": true,
"scope": "license",
"targets": {
"talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
"licenses": [
"lic_ba2q8v1m3n7p4r6s9t0wxyhk5z"
],
"facets": [
"fct_v1m3n7p4r6s9t0wxyhk5zba2q8"
],
"mandate": null
},
"status": "pending_acknowledgement",
"initiated_by": "talent",
"for_cause": false,
"cause": null,
"note": null,
"effective_at": "2026-10-17T18:03:40Z",
"post_revocation": {
"policy": "retain",
"withdraw_by": null
},
"required_actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"provider_copies": [
{
"facet": "fct_v1m3n7p4r6s9t0wxyhk5zba2q8",
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c"
}
],
"affected": {
"checks_denied": 3,
"generations_denied": 0,
"sessions_terminated": 1,
"released_outputs": 418
},
"acknowledge_by": "2026-10-18T18:03:40Z",
"acknowledgements": [],
"created_at": "2026-10-17T18:03:40Z"
}{
"type": "https://docs.reflections.ai/errors/invalid_api_key",
"title": "The API key is not valid",
"status": 401,
"code": "invalid_api_key",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "https://docs.reflections.ai/errors/account_not_connected",
"title": "The licensee has not connected your platform",
"status": 403,
"code": "account_not_connected",
"detail": "acct_2q8v1m3n7p4r6s9t0wxyhk5zba has no active connection with your account.",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "https://docs.reflections.ai/errors/resource_not_found",
"title": "No such object",
"status": 404,
"code": "resource_not_found",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "https://docs.reflections.ai/errors/rate_limited",
"title": "Too many requests",
"status": 429,
"code": "rate_limited",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "invalid_request",
"request_id": "<string>",
"detail": "<string>",
"param": "<string>",
"doc_url": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "invalid_request",
"request_id": "<string>",
"detail": "<string>",
"param": "<string>",
"doc_url": "<string>"
}Retrieve a revocation
Planned contract — unavailable in test and live modes. This operation is a protocol reference, not a callable endpoint. Start with the working sandbox quickstart.
Returns a revocation: what it cut, the actions it requires, its deadlines, and every acknowledgement received so far. A representative can retrieve the revocations of every talent it represents.
Restricted keys need revocations:write.
: "${REFLECTIONS_KEY:?Set REFLECTIONS_KEY before running this example}"
curl --fail-with-body --max-time 30 'https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6' \
-H "Authorization: Bearer $REFLECTIONS_KEY" \
-H "Reflections-Version: 2026-10-15"import { env, exit } from "node:process";
const apiKey = env.REFLECTIONS_KEY;
if (!apiKey) throw new Error("Set REFLECTIONS_KEY before running this example");
const response = await fetch("https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6", {
method: "GET",
headers: {
Authorization: `Bearer ${apiKey}`,
"Reflections-Version": "2026-10-15",
},
signal: AbortSignal.timeout(30_000),
});
const responseBody = await response.text();
if (!response.ok) {
console.error(`HTTP ${response.status}: ${responseBody}`);
exit(1);
}
console.log(responseBody);
import os
from urllib.error import HTTPError
from urllib.request import Request, urlopen
apiKey = os.environ["REFLECTIONS_KEY"]
if not apiKey:
raise ValueError("Set REFLECTIONS_KEY before running this example")
headers = {
"Authorization": f"Bearer {apiKey}",
"Reflections-Version": "2026-10-15",
}
request = Request("https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6",
method="GET", headers=headers)
try:
with urlopen(request, timeout=30) as response:
print(response.read().decode("utf-8"))
except HTTPError as error:
error_body = error.read().decode("utf-8")
raise RuntimeError(f"HTTP {error.code}: {error_body}") from error
package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
apiKey := os.Getenv("REFLECTIONS_KEY")
if apiKey == "" {
panic("Set REFLECTIONS_KEY before running this example")
}
request, err := http.NewRequest("GET", "https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6", nil)
if err != nil {
panic(err)
}
request.Header.Set("Authorization", "Bearer " + apiKey)
request.Header.Set("Reflections-Version", "2026-10-15")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil {
panic(err)
}
defer response.Body.Close()
responseBody, err := io.ReadAll(response.Body)
if err != nil {
panic(err)
}
if response.StatusCode < 200 || response.StatusCode >= 300 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, responseBody))
}
fmt.Print(string(responseBody))
}
{
"id": "rvk_s9t0wxyhk5zba2q8v1m3n7p4r6",
"object": "revocation",
"livemode": true,
"scope": "license",
"targets": {
"talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
"licenses": [
"lic_ba2q8v1m3n7p4r6s9t0wxyhk5z"
],
"facets": [
"fct_v1m3n7p4r6s9t0wxyhk5zba2q8"
],
"mandate": null
},
"status": "pending_acknowledgement",
"initiated_by": "talent",
"for_cause": false,
"cause": null,
"note": null,
"effective_at": "2026-10-17T18:03:40Z",
"post_revocation": {
"policy": "retain",
"withdraw_by": null
},
"required_actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"provider_copies": [
{
"facet": "fct_v1m3n7p4r6s9t0wxyhk5zba2q8",
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c"
}
],
"affected": {
"checks_denied": 3,
"generations_denied": 0,
"sessions_terminated": 1,
"released_outputs": 418
},
"acknowledge_by": "2026-10-18T18:03:40Z",
"acknowledgements": [],
"created_at": "2026-10-17T18:03:40Z"
}{
"type": "https://docs.reflections.ai/errors/invalid_api_key",
"title": "The API key is not valid",
"status": 401,
"code": "invalid_api_key",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "https://docs.reflections.ai/errors/account_not_connected",
"title": "The licensee has not connected your platform",
"status": 403,
"code": "account_not_connected",
"detail": "acct_2q8v1m3n7p4r6s9t0wxyhk5zba has no active connection with your account.",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "https://docs.reflections.ai/errors/resource_not_found",
"title": "No such object",
"status": 404,
"code": "resource_not_found",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "https://docs.reflections.ai/errors/rate_limited",
"title": "Too many requests",
"status": 429,
"code": "rate_limited",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "invalid_request",
"request_id": "<string>",
"detail": "<string>",
"param": "<string>",
"doc_url": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "invalid_request",
"request_id": "<string>",
"detail": "<string>",
"param": "<string>",
"doc_url": "<string>"
}Authorizations
Your secret key, rk_test_… or rk_live_…, sent as Authorization: Bearer <key>. Keep it
on your server. Restricted keys carry only the scopes you give them.
Headers
The dated API version. Defaults to the version your account is pinned to.
"2026-10-15"
Act for a connected licensee. The value is the licensee's account ID. Requires an active connection between that account and yours.
^acct_[0-9a-hjkmnp-tv-z]{26}$Path Parameters
The revocation's ID.
^rvk_[0-9a-hjkmnp-tv-z]{26}$Response
The revocation.
The revocation's ID. Pass it as after to read the revocations created after it.
^rvk_[0-9a-hjkmnp-tv-z]{26}$Always revocation.
"revocation"true in live mode, false for an object created with a test key.
license: one license. facet: a facet withdrawn, which narrows every license that covers it. mandate: a representative's authority ended. talent: consent withdrawn everywhere.
license, facet, mandate, talent What the revocation cuts. Which fields are set depends on scope.
Show child attributes
Show child attributes
pending_acknowledgement until every required action is acknowledged, then
acknowledged, or overdue if a deadline passes first.
pending_acknowledgement, acknowledged, overdue Who revoked: the talent in the Talent Portal, a representative whose mandate has
revoke, or Reflections.
talent, representative, reflections When the revocation took effect. acknowledge_by is 24 hours later.
What every platform that used the targets must do and acknowledge.
stop_generation: issue nothing new under the targets. purge_cached_decisions: drop
cached checks and authorizations. delete_provider_copies: delete copies held at model
providers, such as voices. cease_distribution: place released outputs nowhere new.
withdraw_outputs: take released outputs down.
stop_generation, purge_cached_decisions, delete_provider_copies, cease_distribution, withdraw_outputs When every required action except withdraw_outputs must be acknowledged: 24 hours
after effective_at.
Each acknowledgement a platform sent, in the order received. Shown on the talent's record.
Show child attributes
Show child attributes
When Reflections recorded the revocation.
Revoked for a breach. Only then can withdraw apply.
For a revocation for cause, the breach, as whoever revoked it stated it.
A note from whoever revoked it.
What happens to outputs released before effective_at, copied from the license's
post_revocation term.
Show child attributes
Show child attributes
Copies at model providers you must delete.
Show child attributes
Show child attributes
What the revocation cut, at effective_at.
Show child attributes
Show child attributes