# 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_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY:?Set REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY before running this example}"
curl --fail-with-body --max-time 30 -X POST 'https://app.reflections.ai/v1/webhook_endpoints/we_5x7z9b1d3f5h7k9m1p3r5t7v9x' \
-H "Authorization: Bearer $REFLECTIONS_KEY" \
-H "Reflections-Version: 2026-10-15" \
-H "Idempotency-Key: $REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
--data-raw '{
"status": "enabled"
}'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_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY;
if (!idempotencyKey) throw new Error("Set REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY before running this example");
const response = await fetch("https://app.reflections.ai/v1/webhook_endpoints/we_5x7z9b1d3f5h7k9m1p3r5t7v9x", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
"status": "enabled"
}),
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_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY"]
if not idempotencyKey:
raise ValueError("Set REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_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({"status": "enabled"}).encode("utf-8")
request = Request("https://app.reflections.ai/v1/webhook_endpoints/we_5x7z9b1d3f5h7k9m1p3r5t7v9x",
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_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY")
if idempotencyKey == "" {
panic("Set REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY before running this example")
}
body := strings.NewReader(`{
"status": "enabled"
}`)
request, err := http.NewRequest("POST", "https://app.reflections.ai/v1/webhook_endpoints/we_5x7z9b1d3f5h7k9m1p3r5t7v9x", 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": "we_y18vejcjn8vvdfs468q4fzhtb2",
"object": "webhook_endpoint",
"livemode": true,
"url": "https://northlight.example/webhooks/revocations",
"events": [
"revocation.created",
"revocation.overdue",
"license.suspended",
"license.resumed",
"license.revoked"
],
"description": "Revocation worker",
"status": "enabled",
"disabled_reason": null,
"api_version": "2026-10-15",
"connected": true,
"secret": null,
"metadata": {
"team": "trust-and-safety"
},
"created_at": "2026-09-14T10:30:00Z"
}Update a webhook endpoint
Planned contract — unavailable in test and live modes. This operation is a protocol reference, not a callable endpoint. Start with the working sandbox quickstart.
Changes the URL, the events, the description, or re-enables a disabled endpoint.
Restricted keys need webhooks:manage.
# 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_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY:?Set REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY before running this example}"
curl --fail-with-body --max-time 30 -X POST 'https://app.reflections.ai/v1/webhook_endpoints/we_5x7z9b1d3f5h7k9m1p3r5t7v9x' \
-H "Authorization: Bearer $REFLECTIONS_KEY" \
-H "Reflections-Version: 2026-10-15" \
-H "Idempotency-Key: $REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
--data-raw '{
"status": "enabled"
}'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_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY;
if (!idempotencyKey) throw new Error("Set REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY before running this example");
const response = await fetch("https://app.reflections.ai/v1/webhook_endpoints/we_5x7z9b1d3f5h7k9m1p3r5t7v9x", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Reflections-Version": "2026-10-15",
"Idempotency-Key": idempotencyKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
"status": "enabled"
}),
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_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY"]
if not idempotencyKey:
raise ValueError("Set REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_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({"status": "enabled"}).encode("utf-8")
request = Request("https://app.reflections.ai/v1/webhook_endpoints/we_5x7z9b1d3f5h7k9m1p3r5t7v9x",
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_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY")
if idempotencyKey == "" {
panic("Set REFLECTIONS_UPDATE_WEBHOOK_ENDPOINT_IDEMPOTENCY_KEY before running this example")
}
body := strings.NewReader(`{
"status": "enabled"
}`)
request, err := http.NewRequest("POST", "https://app.reflections.ai/v1/webhook_endpoints/we_5x7z9b1d3f5h7k9m1p3r5t7v9x", 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": "we_y18vejcjn8vvdfs468q4fzhtb2",
"object": "webhook_endpoint",
"livemode": true,
"url": "https://northlight.example/webhooks/revocations",
"events": [
"revocation.created",
"revocation.overdue",
"license.suspended",
"license.resumed",
"license.revoked"
],
"description": "Revocation worker",
"status": "enabled",
"disabled_reason": null,
"api_version": "2026-10-15",
"connected": true,
"secret": null,
"metadata": {
"team": "trust-and-safety"
},
"created_at": "2026-09-14T10:30:00Z"
}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"
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 endpoint's ID.
^we_[0-9a-hjkmnp-tv-z]{26}$Body
A new HTTPS URL.
Replaces the event types to send. ["*"] for every type.
1license.issued, license.accepted, license.revised, license.revision_pending, license.revision_declined, license.suspended, license.resumed, license.revoked, license.expired, license.declined, license_request.created, license_request.signed, license_request.declined, license_draft.signed, license_draft.declined, check.resolved, escalation.created, generation.allowed, generation.released, generation.denied, generation.expired, session.terminated, revocation.created, revocation.overdue, connection.created, connection.revoked, facet.updated, talent.updated, statement.issued, statement.disputed, mandate.created, mandate.ended, webhook_endpoint.disabled Replaces your label for the endpoint.
500Re-enable a disabled endpoint.
enabled Replaces the endpoint's metadata.
Show child attributes
Show child attributes
Response
The updated endpoint.
The endpoint's ID, we_….
^we_[0-9a-hjkmnp-tv-z]{26}$Always webhook_endpoint.
"webhook_endpoint"true for an endpoint created with a live key, which receives only live events. false
for one created with a test key, which receives only test events.
The HTTPS URL events are sent to.
The event types sent to this endpoint. ["*"] sends every type, including types added
later.
license.issued, license.accepted, license.revised, license.revision_pending, license.revision_declined, license.suspended, license.resumed, license.revoked, license.expired, license.declined, license_request.created, license_request.signed, license_request.declined, license_draft.signed, license_draft.declined, check.resolved, escalation.created, generation.allowed, generation.released, generation.denied, generation.expired, session.terminated, revocation.created, revocation.overdue, connection.created, connection.revoked, facet.updated, talent.updated, statement.issued, statement.disputed, mandate.created, mandate.ended, webhook_endpoint.disabled enabled, or disabled after every delivery failed for 5 days. Re-enable a disabled
endpoint by updating it with status: enabled.
enabled, disabled The version events are rendered in. Set when the endpoint is created; it cannot be changed.
When the endpoint was created.
Your label for the endpoint. null when you set none.
Why Reflections disabled the endpoint. null while enabled.
Whether the endpoint also receives events about connected licensees' objects. Those
events carry the licensee's ID in account.
whsec_…. Returned only when the endpoint is created or its secret rotated.
Keys and values of your own.
Show child attributes
Show child attributes