# 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_RENEW_SESSION_IDEMPOTENCY_KEY:?Set REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY before running this example}"
curl --fail-with-body --max-time 30 -X POST 'https://app.reflections.ai/v1/sessions/ses_q8v1m3n7p4r6s9t0wxyhk5zba2/renew' \
-H "Authorization: Bearer $REFLECTIONS_KEY" \
-H "Reflections-Version: 2026-10-15" \
-H "Idempotency-Key: $REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY"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_RENEW_SESSION_IDEMPOTENCY_KEY;
if (!idempotencyKey) throw new Error("Set REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY before running this example");
const response = await fetch("https://app.reflections.ai/v1/sessions/ses_q8v1m3n7p4r6s9t0wxyhk5zba2/renew", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
},
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
# 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_RENEW_SESSION_IDEMPOTENCY_KEY"]
if not idempotencyKey:
raise ValueError("Set REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY before running this example")
headers = {
"Authorization": f"Bearer {apiKey}",
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
}
request = Request("https://app.reflections.ai/v1/sessions/ses_q8v1m3n7p4r6s9t0wxyhk5zba2/renew",
method="POST", 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() {
// 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_RENEW_SESSION_IDEMPOTENCY_KEY")
if idempotencyKey == "" {
panic("Set REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY before running this example")
}
request, err := http.NewRequest("POST", "https://app.reflections.ai/v1/sessions/ses_q8v1m3n7p4r6s9t0wxyhk5zba2/renew", nil)
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)
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))
}
{
"token": "eyJhbGciOiJFUzI1NiIsImtpZCI6InJmbC0yMDI2LTEwLWRvY3MzIiwidHlwIjoidGxwLXNlc3Npb24rand0In0.eyJhdWQiOiJhY2N0XzdwNHI2czl0MHd4eWhrNXpiYTJxOHYxbTNuIiwiZXhwIjoxNzkyMjYwMzAwLCJpYXQiOjE3OTIyNjAwMDAsImlzcyI6Imh0dHBzOi8vYXBwLnJlZmxlY3Rpb25zLmFpIiwianRpIjoic2VzX3E4djFtM243cDRyNnM5dDB3eHloazV6YmEyIiwic3ViIjoiYWNjdF83cDRyNnM5dDB3eHloazV6YmEycTh2MW0zbiIsInRscCI6eyJjaGVjayI6ImNoa19uN3A0cjZzOXQwd3h5aGs1emJhMnE4djFtMyIsImV1IjoiM2Y5YzFhN2U1YjJkOGY0MDYxYzNlOWE3YjVkMmY4MDE2ZTRjOWEzYjdkMWY1ZTJjOGE2YjRkMGY5ZTNjN2ExNSIsImZhY2V0cyI6WyJmY3RfdjFtM243cDRyNnM5dDB3eHloazV6YmEycTgiXSwibGljZW5zZXMiOlt7ImxpY2Vuc2UiOiJsaWNfYmEycTh2MW0zbjdwNHI2czl0MHd4eWhrNXoiLCJyZXZpc2lvbiI6Imxydl83cDRyNnM5dDB3eHloazV6YmEycTh2MW0zbiIsInRhbGVudCI6InRhbF85dDB3eHloazV6YmEycTh2MW0zbjdwNHI2cyIsInRlcm1zX2RpZ2VzdCI6InNoYTI1Njo4ZTBhMmM0ZTZiOGQwZjJhNGM2ZThiMGQyZjRhNmM4ZTBiMmQ0ZjZhOGMwZTJiNGQ2ZjhhMGMyZTRiNmQ4ZjBhIn1dLCJzYW1wbGluZyI6eyJhdWRpb193aW5kb3dfbWF4IjoiUFQxNVMiLCJ0cmFuc2NyaXB0IjoiZXZlcnlfdHVybiJ9LCJzZXNzaW9uIjoic2VzX3E4djFtM243cDRyNnM5dDB3eHloazV6YmEyIiwidGFsZW50IjpbInRhbF85dDB3eHloazV6YmEycTh2MW0zbjdwNHI2cyJdLCJ1c2UiOnsiY2hhbm5lbHMiOlsiaW5fYXBwIl0sImNvbW1lcmNpYWwiOmZhbHNlLCJraW5kIjoiaW1wZXJzb25hdGlvbiIsIm1vZGFsaXR5Ijoic3BlZWNoIiwicHVycG9zZSI6InBlcnNvbmFsIiwidGVycml0b3JpZXMiOlsiVVMiXX0sInZlciI6IjEuMCJ9fQ.RD_dRcXCqGHhYvg-PV3b1JIAoAX-WzVp02x6j-eSzmhYFxuZvniuJVrhJuHmzlFq_FYr6smqYXHQzb5p8DI0gA",
"expires_at": "2026-10-17T18:06: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/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>"
}Renew a session
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 fresh session token. Renew every renew_every (60 seconds). Renewal fails with
session_not_active once the license is revoked, suspended or ends, or the session was
terminated; stop output at once when it fails.
Restricted keys need sessions: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_RENEW_SESSION_IDEMPOTENCY_KEY:?Set REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY before running this example}"
curl --fail-with-body --max-time 30 -X POST 'https://app.reflections.ai/v1/sessions/ses_q8v1m3n7p4r6s9t0wxyhk5zba2/renew' \
-H "Authorization: Bearer $REFLECTIONS_KEY" \
-H "Reflections-Version: 2026-10-15" \
-H "Idempotency-Key: $REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY"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_RENEW_SESSION_IDEMPOTENCY_KEY;
if (!idempotencyKey) throw new Error("Set REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY before running this example");
const response = await fetch("https://app.reflections.ai/v1/sessions/ses_q8v1m3n7p4r6s9t0wxyhk5zba2/renew", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
},
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
# 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_RENEW_SESSION_IDEMPOTENCY_KEY"]
if not idempotencyKey:
raise ValueError("Set REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY before running this example")
headers = {
"Authorization": f"Bearer {apiKey}",
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
}
request = Request("https://app.reflections.ai/v1/sessions/ses_q8v1m3n7p4r6s9t0wxyhk5zba2/renew",
method="POST", 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() {
// 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_RENEW_SESSION_IDEMPOTENCY_KEY")
if idempotencyKey == "" {
panic("Set REFLECTIONS_RENEW_SESSION_IDEMPOTENCY_KEY before running this example")
}
request, err := http.NewRequest("POST", "https://app.reflections.ai/v1/sessions/ses_q8v1m3n7p4r6s9t0wxyhk5zba2/renew", nil)
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)
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))
}
{
"token": "eyJhbGciOiJFUzI1NiIsImtpZCI6InJmbC0yMDI2LTEwLWRvY3MzIiwidHlwIjoidGxwLXNlc3Npb24rand0In0.eyJhdWQiOiJhY2N0XzdwNHI2czl0MHd4eWhrNXpiYTJxOHYxbTNuIiwiZXhwIjoxNzkyMjYwMzAwLCJpYXQiOjE3OTIyNjAwMDAsImlzcyI6Imh0dHBzOi8vYXBwLnJlZmxlY3Rpb25zLmFpIiwianRpIjoic2VzX3E4djFtM243cDRyNnM5dDB3eHloazV6YmEyIiwic3ViIjoiYWNjdF83cDRyNnM5dDB3eHloazV6YmEycTh2MW0zbiIsInRscCI6eyJjaGVjayI6ImNoa19uN3A0cjZzOXQwd3h5aGs1emJhMnE4djFtMyIsImV1IjoiM2Y5YzFhN2U1YjJkOGY0MDYxYzNlOWE3YjVkMmY4MDE2ZTRjOWEzYjdkMWY1ZTJjOGE2YjRkMGY5ZTNjN2ExNSIsImZhY2V0cyI6WyJmY3RfdjFtM243cDRyNnM5dDB3eHloazV6YmEycTgiXSwibGljZW5zZXMiOlt7ImxpY2Vuc2UiOiJsaWNfYmEycTh2MW0zbjdwNHI2czl0MHd4eWhrNXoiLCJyZXZpc2lvbiI6Imxydl83cDRyNnM5dDB3eHloazV6YmEycTh2MW0zbiIsInRhbGVudCI6InRhbF85dDB3eHloazV6YmEycTh2MW0zbjdwNHI2cyIsInRlcm1zX2RpZ2VzdCI6InNoYTI1Njo4ZTBhMmM0ZTZiOGQwZjJhNGM2ZThiMGQyZjRhNmM4ZTBiMmQ0ZjZhOGMwZTJiNGQ2ZjhhMGMyZTRiNmQ4ZjBhIn1dLCJzYW1wbGluZyI6eyJhdWRpb193aW5kb3dfbWF4IjoiUFQxNVMiLCJ0cmFuc2NyaXB0IjoiZXZlcnlfdHVybiJ9LCJzZXNzaW9uIjoic2VzX3E4djFtM243cDRyNnM5dDB3eHloazV6YmEyIiwidGFsZW50IjpbInRhbF85dDB3eHloazV6YmEycTh2MW0zbjdwNHI2cyJdLCJ1c2UiOnsiY2hhbm5lbHMiOlsiaW5fYXBwIl0sImNvbW1lcmNpYWwiOmZhbHNlLCJraW5kIjoiaW1wZXJzb25hdGlvbiIsIm1vZGFsaXR5Ijoic3BlZWNoIiwicHVycG9zZSI6InBlcnNvbmFsIiwidGVycml0b3JpZXMiOlsiVVMiXX0sInZlciI6IjEuMCJ9fQ.RD_dRcXCqGHhYvg-PV3b1JIAoAX-WzVp02x6j-eSzmhYFxuZvniuJVrhJuHmzlFq_FYr6smqYXHQzb5p8DI0gA",
"expires_at": "2026-10-17T18:06: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/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 session's ID.
^ses_[0-9a-hjkmnp-tv-z]{26}$