# Set a unique key once per new action; persist it and reuse it for every retry.
: "${REFLECTIONS_KEY:?Set REFLECTIONS_KEY before running this example}"
: "${REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY:?Set REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY before running this example}"
curl --fail-with-body --max-time 30 -X POST 'https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6/acknowledgements' \
-H "Authorization: Bearer $REFLECTIONS_KEY" \
-H "Reflections-Version: 2026-10-15" \
-H "Idempotency-Key: $REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
--data-raw '{
"actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z"
}
],
"note": "Voice deleted at the provider. Reuse caches purged."
}'import { env, exit } from "node:process";
// Set a unique key once per new action; persist it and reuse it for every retry.
const apiKey = env.REFLECTIONS_KEY;
if (!apiKey) throw new Error("Set REFLECTIONS_KEY before running this example");
const idempotencyKey = env.REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY;
if (!idempotencyKey) throw new Error("Set REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY before running this example");
const response = await fetch("https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6/acknowledgements", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
"actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z"
}
],
"note": "Voice deleted at the provider. Reuse caches purged."
}),
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 json
import os
from urllib.error import HTTPError
from urllib.request import Request, urlopen
# Set a unique key once per new action; persist it and reuse it for every retry.
apiKey = os.environ["REFLECTIONS_KEY"]
if not apiKey:
raise ValueError("Set REFLECTIONS_KEY before running this example")
idempotencyKey = os.environ["REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY"]
if not idempotencyKey:
raise ValueError("Set REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY before running this example")
headers = {
"Authorization": f"Bearer {apiKey}",
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
"Content-Type": "application/json",
}
data = json.dumps({
"actions": ["stop_generation", "purge_cached_decisions", "delete_provider_copies"],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z",
},
],
"note": "Voice deleted at the provider. Reuse caches purged.",
}).encode("utf-8")
request = Request("https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6/acknowledgements",
method="POST", headers=headers, data=data)
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"
"strings"
"time"
)
func main() {
// Set a unique key once per new action; persist it and reuse it for every retry.
apiKey := os.Getenv("REFLECTIONS_KEY")
if apiKey == "" {
panic("Set REFLECTIONS_KEY before running this example")
}
idempotencyKey := os.Getenv("REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY")
if idempotencyKey == "" {
panic("Set REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY before running this example")
}
body := strings.NewReader(`{
"actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z"
}
],
"note": "Voice deleted at the provider. Reuse caches purged."
}`)
request, err := http.NewRequest("POST", "https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6/acknowledgements", body)
if err != nil {
panic(err)
}
request.Header.Set("Authorization", "Bearer " + apiKey)
request.Header.Set("Reflections-Version", "2026-10-15")
request.Header.Set("Idempotency-Key", idempotencyKey)
request.Header.Set("Content-Type", "application/json")
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": "acknowledged",
"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": [
{
"account": "acct_7p4r6s9t0wxyhk5zba2q8v1m3n",
"actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z"
}
],
"note": "Voice deleted at the provider. Reuse caches purged.",
"acknowledged_at": "2026-10-17T18:09:31Z"
}
],
"created_at": "2026-10-17T18:03:40Z"
}{
"type": "https://docs.reflections.ai/errors/parameter_invalid",
"title": "A parameter is invalid",
"status": 400,
"code": "parameter_invalid",
"param": "use.territories[1]",
"detail": "\"UK\" is not an ISO 3166-1 alpha-2 code. Use \"GB\".",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"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/idempotency_key_in_use",
"title": "A request with this key is still running",
"status": 409,
"code": "idempotency_key_in_use",
"detail": "Retry with the same key after a short wait.",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "https://docs.reflections.ai/errors/idempotency_key_reused",
"title": "This key was used for a different request",
"status": 422,
"code": "idempotency_key_reused",
"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>"
}Acknowledge 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.
Attests that your platform has done what the revocation requires: stopped generating,
purged cached decisions, deleted copies held at providers, and applied post_revocation
to released outputs. Acknowledge every action but withdraw_outputs before
acknowledge_by, and withdraw_outputs before post_revocation.withdraw_by; you may
call this more than once. Acknowledgements are shown on the talent’s record.
Restricted keys need revocations:write.
# Set a unique key once per new action; persist it and reuse it for every retry.
: "${REFLECTIONS_KEY:?Set REFLECTIONS_KEY before running this example}"
: "${REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY:?Set REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY before running this example}"
curl --fail-with-body --max-time 30 -X POST 'https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6/acknowledgements' \
-H "Authorization: Bearer $REFLECTIONS_KEY" \
-H "Reflections-Version: 2026-10-15" \
-H "Idempotency-Key: $REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
--data-raw '{
"actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z"
}
],
"note": "Voice deleted at the provider. Reuse caches purged."
}'import { env, exit } from "node:process";
// Set a unique key once per new action; persist it and reuse it for every retry.
const apiKey = env.REFLECTIONS_KEY;
if (!apiKey) throw new Error("Set REFLECTIONS_KEY before running this example");
const idempotencyKey = env.REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY;
if (!idempotencyKey) throw new Error("Set REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY before running this example");
const response = await fetch("https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6/acknowledgements", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
"actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z"
}
],
"note": "Voice deleted at the provider. Reuse caches purged."
}),
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 json
import os
from urllib.error import HTTPError
from urllib.request import Request, urlopen
# Set a unique key once per new action; persist it and reuse it for every retry.
apiKey = os.environ["REFLECTIONS_KEY"]
if not apiKey:
raise ValueError("Set REFLECTIONS_KEY before running this example")
idempotencyKey = os.environ["REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY"]
if not idempotencyKey:
raise ValueError("Set REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY before running this example")
headers = {
"Authorization": f"Bearer {apiKey}",
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
"Content-Type": "application/json",
}
data = json.dumps({
"actions": ["stop_generation", "purge_cached_decisions", "delete_provider_copies"],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z",
},
],
"note": "Voice deleted at the provider. Reuse caches purged.",
}).encode("utf-8")
request = Request("https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6/acknowledgements",
method="POST", headers=headers, data=data)
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"
"strings"
"time"
)
func main() {
// Set a unique key once per new action; persist it and reuse it for every retry.
apiKey := os.Getenv("REFLECTIONS_KEY")
if apiKey == "" {
panic("Set REFLECTIONS_KEY before running this example")
}
idempotencyKey := os.Getenv("REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY")
if idempotencyKey == "" {
panic("Set REFLECTIONS_CREATE_REVOCATION_ACKNOWLEDGEMENT_IDEMPOTENCY_KEY before running this example")
}
body := strings.NewReader(`{
"actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z"
}
],
"note": "Voice deleted at the provider. Reuse caches purged."
}`)
request, err := http.NewRequest("POST", "https://app.reflections.ai/v1/revocations/rvk_s9t0wxyhk5zba2q8v1m3n7p4r6/acknowledgements", body)
if err != nil {
panic(err)
}
request.Header.Set("Authorization", "Bearer " + apiKey)
request.Header.Set("Reflections-Version", "2026-10-15")
request.Header.Set("Idempotency-Key", idempotencyKey)
request.Header.Set("Content-Type", "application/json")
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": "acknowledged",
"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": [
{
"account": "acct_7p4r6s9t0wxyhk5zba2q8v1m3n",
"actions": [
"stop_generation",
"purge_cached_decisions",
"delete_provider_copies"
],
"deleted_copies": [
{
"provider": "example-voice-provider",
"external_id": "vx_4f9a2c",
"deleted_at": "2026-10-17T18:09:12Z"
}
],
"note": "Voice deleted at the provider. Reuse caches purged.",
"acknowledged_at": "2026-10-17T18:09:31Z"
}
],
"created_at": "2026-10-17T18:03:40Z"
}{
"type": "https://docs.reflections.ai/errors/parameter_invalid",
"title": "A parameter is invalid",
"status": 400,
"code": "parameter_invalid",
"param": "use.territories[1]",
"detail": "\"UK\" is not an ISO 3166-1 alpha-2 code. Use \"GB\".",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"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/idempotency_key_in_use",
"title": "A request with this key is still running",
"status": 409,
"code": "idempotency_key_in_use",
"detail": "Retry with the same key after a short wait.",
"request_id": "req_8f2k4m6p8r0t2v4x6z8b0d2f4h"
}{
"type": "https://docs.reflections.ai/errors/idempotency_key_reused",
"title": "This key was used for a different request",
"status": 422,
"code": "idempotency_key_reused",
"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}$A unique key for this operation, up to 255 characters. In test mode, POST keys are scoped to your account and mode and bind the endpoint and body for 24 hours. A different endpoint or body with the same key is refused.
Initial live check and generation creation require a nonempty key. Each operation has a
separate account-scoped namespace; retain the same API key, body and idempotency key for
retries within 24 hours of creation. A pending check returns 202 with status: "checking".
Completed checks replay their sealed response; successful generation POSTs replay the
original accepted 202, so use GET for current state. Live verification is a read-only
query that returns a fresh verification ID on each call, without exact response caching.
The broader delegated-account contract also scopes keys to Reflections-Account;
delegated requests and the other planned live POST operations remain unsupported.
255Path Parameters
The revocation's ID.
^rvk_[0-9a-hjkmnp-tv-z]{26}$Body
The actions you completed. By acknowledge_by, acknowledge every required action
except withdraw_outputs. Acknowledge withdraw_outputs in a later call, by
post_revocation.withdraw_by. Each call adds to the revocation's acknowledgements.
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 Each copy from provider_copies you deleted. List every one when you acknowledge
delete_provider_copies.
Show child attributes
Show child attributes
Shown with your acknowledgement on the talent's record.
1000Response
The revocation, with your acknowledgement.
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