: "${REFLECTIONS_KEY:?Set REFLECTIONS_KEY before running this example}"
curl --fail-with-body --max-time 30 'https://app.reflections.ai/v1/escalations/esc_t0wxyhk5zba2q8v1m3n7p4r6s9' \
-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/escalations/esc_t0wxyhk5zba2q8v1m3n7p4r6s9", {
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/escalations/esc_t0wxyhk5zba2q8v1m3n7p4r6s9",
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/escalations/esc_t0wxyhk5zba2q8v1m3n7p4r6s9", 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": "esc_t0wxyhk5zba2q8v1m3n7p4r6s9",
"object": "escalation",
"livemode": true,
"reason": "judgment",
"reviewer": "talent",
"status": "open",
"expires_at": "2026-10-24T18:04:00Z",
"resolved_at": null,
"note": null,
"subject": {
"object": "check",
"id": "chk_r6s9t0wxyhk5zba2q8v1m3n7p4"
},
"talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
"license": "lic_k5zba2q8v1m3n7p4r6s9t0wxyh",
"license_revision": "lrv_p4r6s9t0wxyhk5zba2q8v1m3n7",
"licensee": "acct_2q8v1m3n7p4r6s9t0wxyhk5zba",
"licensee_name": "Ridgeline",
"platform": "acct_7p4r6s9t0wxyhk5zba2q8v1m3n",
"platform_name": "Northlight",
"use": {
"modality": "image",
"kind": "depiction",
"purpose": "advertising",
"commercial": true,
"channels": [
"social"
],
"territories": [
"US"
]
},
"inputs": [
{
"role": "prompt",
"text": "Maya Okafor at a trailhead café with two friends, paper cups on the table, morning light"
}
],
"reasons": [
{
"code": "prohibited_custom_term",
"stage": "check",
"talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
"term": "license:lic_k5zba2q8v1m3n7p4r6s9t0wxyh/terms.neverExtras",
"sentence": "Do not show alcohol or tobacco."
}
],
"findings": [],
"artifact": null,
"request_digest": "sha256:c3e5a7b9d1f3c5e7a9b1d3f5c7e9a1b3d5f7c9e1a3b5d7f9c1e3a5b7d9f1c3e5",
"review_url": "https://app.reflections.ai/review/esc_t0wxyhk5zba2q8v1m3n7p4r6s9",
"decision": null,
"decided_by": null,
"created_at": "2026-10-17T18:04:00Z"
}{
"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/mandate_required",
"title": "No mandate with the needed power",
"status": 403,
"code": "mandate_required",
"detail": "Your mandate for tal_9t0wxyhk5zba2q8v1m3n7p4r6s does not include review_outputs.",
"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 an escalation
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 an escalation with everything a reviewer needs: the request as the platform sent it,
the use, the licensee and platform, the term the question rests on, and, for a held output,
the findings on its bytes and a link to view it. Inputs sent with
prompt_handling: "withheld" show only their role and digest.
Restricted keys need escalations:write.
: "${REFLECTIONS_KEY:?Set REFLECTIONS_KEY before running this example}"
curl --fail-with-body --max-time 30 'https://app.reflections.ai/v1/escalations/esc_t0wxyhk5zba2q8v1m3n7p4r6s9' \
-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/escalations/esc_t0wxyhk5zba2q8v1m3n7p4r6s9", {
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/escalations/esc_t0wxyhk5zba2q8v1m3n7p4r6s9",
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/escalations/esc_t0wxyhk5zba2q8v1m3n7p4r6s9", 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": "esc_t0wxyhk5zba2q8v1m3n7p4r6s9",
"object": "escalation",
"livemode": true,
"reason": "judgment",
"reviewer": "talent",
"status": "open",
"expires_at": "2026-10-24T18:04:00Z",
"resolved_at": null,
"note": null,
"subject": {
"object": "check",
"id": "chk_r6s9t0wxyhk5zba2q8v1m3n7p4"
},
"talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
"license": "lic_k5zba2q8v1m3n7p4r6s9t0wxyh",
"license_revision": "lrv_p4r6s9t0wxyhk5zba2q8v1m3n7",
"licensee": "acct_2q8v1m3n7p4r6s9t0wxyhk5zba",
"licensee_name": "Ridgeline",
"platform": "acct_7p4r6s9t0wxyhk5zba2q8v1m3n",
"platform_name": "Northlight",
"use": {
"modality": "image",
"kind": "depiction",
"purpose": "advertising",
"commercial": true,
"channels": [
"social"
],
"territories": [
"US"
]
},
"inputs": [
{
"role": "prompt",
"text": "Maya Okafor at a trailhead café with two friends, paper cups on the table, morning light"
}
],
"reasons": [
{
"code": "prohibited_custom_term",
"stage": "check",
"talent": "tal_9t0wxyhk5zba2q8v1m3n7p4r6s",
"term": "license:lic_k5zba2q8v1m3n7p4r6s9t0wxyh/terms.neverExtras",
"sentence": "Do not show alcohol or tobacco."
}
],
"findings": [],
"artifact": null,
"request_digest": "sha256:c3e5a7b9d1f3c5e7a9b1d3f5c7e9a1b3d5f7c9e1a3b5d7f9c1e3a5b7d9f1c3e5",
"review_url": "https://app.reflections.ai/review/esc_t0wxyhk5zba2q8v1m3n7p4r6s9",
"decision": null,
"decided_by": null,
"created_at": "2026-10-17T18:04:00Z"
}{
"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/mandate_required",
"title": "No mandate with the needed power",
"status": 403,
"code": "mandate_required",
"detail": "Your mandate for tal_9t0wxyhk5zba2q8v1m3n7p4r6s does not include review_outputs.",
"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"
Path Parameters
The escalation's ID.
^esc_[0-9a-hjkmnp-tv-z]{26}$Response
The escalation.
An escalation with the request, use and findings a reviewer needs.
The escalation's ID, esc_ followed by 26 characters.
^esc_[0-9a-hjkmnp-tv-z]{26}$judgment: a rule needs a person to read it. unverifiable: a protected attribute
could not be confirmed. evaluation_unavailable: the check could not finish.
release_review: every output under this license is released by a person.
judgment, unverifiable, evaluation_unavailable, release_review talent: the talent, or a representative whose mandate has review_outputs.
representative: only the talent's representatives. reflections: Reflections trust
and safety, under a platform license.
talent, representative, reflections open until it closes: allowed or denied by the reviewer, expired at
expires_at, or cancelled when you cancel the check, withdraw the output, or another
talent's escalation decides the check.
open, allowed, denied, expired, cancelled When an unanswered escalation becomes deny: 7 days after it opens, or the license's
shorter escalation_window.
Always escalation.
"escalation"true in live mode, false in test mode.
What waits on the decision.
Show child attributes
Show child attributes
The talent whose side decides. When a check escalates for several talent, each has their own escalation.
^tal_[0-9a-hjkmnp-tv-z]{26}$The license the request was checked under.
^lic_[0-9a-hjkmnp-tv-z]{26}$The account that holds license.
^acct_[0-9a-hjkmnp-tv-z]{26}$The platform that ran the check or submitted the output.
^acct_[0-9a-hjkmnp-tv-z]{26}$The use the platform asked for on the check.
Show child attributes
Show child attributes
The request_digest of the check. Allowing an escalated check covers exactly this
request.
^sha256:[0-9a-f]{64}$When the check escalated or the output was held.
When the escalation was decided, expired or cancelled. Null while open.
The reviewer's note, if they wrote one.
500The revision of license the request was checked against.
^lrv_[0-9a-hjkmnp-tv-z]{26}$The licensee's account name.
The platform's account name.
The request as the platform sent it. Media inputs carry a url that opens for 15
minutes. Text sent withheld appears as role and sha256 only.
Show child attributes
Show child attributes
What raised the question, with the talent's term.
Show child attributes
Show child attributes
For a held output, what Reflections recorded on its bytes.
Show child attributes
Show child attributes
For a held output, the clean bytes to review.
Show child attributes
Show child attributes
The Talent Portal page where a person with authority reviews it and decides. Present while open.
The decision a person recorded, allow or deny. null until one is recorded.
allow, deny, null Who resolved it.
Show child attributes
Show child attributes