Observability
Manage broadcast destinations for usage, error, and memory events.
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /v1/observability/destinations | API Key | List destinations |
| POST | /v1/observability/destinations | API Key | Add a destination |
| PUT | /v1/observability/destinations/:id | API Key | Update a destination |
| DELETE | /v1/observability/destinations/:id | API Key | Remove a destination |
| POST | /v1/observability/test/:id | API Key | Send test event |
| GET | /v1/observability/config | API Key | Get broadcast config |
| PUT | /v1/observability/config | API Key | Enable/disable broadcasting |
| GET | /v1/observability/templates | API Key | List integration templates |
| GET | /v1/observability/templates/:provider | API Key | Get template for a platform |
Add a destination
curl -X POST https://api.brainstormrouter.com/v1/observability/destinations \
-H "Authorization: Bearer br_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Analytics Webhook",
"type": "webhook",
"config": {"url": "https://example.com/ingest"},
"event_types": ["usage", "error"],
"batch": {"max_size": 50, "flush_interval_ms": 5000}
}'
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name |
type | string | Yes | webhook, otlp, datadog, splunk, posthog, s3, custom |
config | object | Yes | Type-specific config (see below) |
event_types | string[] | No | Filter: usage, audit, quality, guardrail, error |
batch | object | No | max_size and flush_interval_ms |
Config by type
| Type | Required fields |
|---|---|
webhook | { url: string } |
otlp | { endpoint: string } |
datadog | { api_key: string } |
splunk | { hec_url: string, hec_token: string } |
posthog | { api_key: string } |
s3 | { bucket: string } |
custom | { url: string } |
Integration templates
Pre-built configs for popular platforms. Reduces setup to "fill in your API key."
# List available templates
curl https://api.brainstormrouter.com/v1/observability/templates \
-H "Authorization: Bearer br_live_..."
# Get specific template
curl https://api.brainstormrouter.com/v1/observability/templates/langfuse \
-H "Authorization: Bearer br_live_..."
Available templates: langfuse, datadog, posthog, s3, splunk
Each template returns:
config_schema— required/optional fields with descriptionsrecommended_event_types— best event types for this platformexample_config— copy-paste config to get started
Test a destination
Sends a synthetic usage event to verify connectivity.
curl -X POST https://api.brainstormrouter.com/v1/observability/test/dest-uuid \
-H "Authorization: Bearer br_live_..."
Enable/disable broadcasting
curl -X PUT https://api.brainstormrouter.com/v1/observability/config \
-H "Authorization: Bearer br_live_..." \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
XDR / SIEM destinations
The /v1/observability/xdr/* endpoints manage SIEM destinations that receive OCSF 1.3.0 events. Five first-party connectors are supported: crowdstrike, sentinel, splunk-ocsf, cortex, datadog-ocsf. See XDR Pipeline for the full event taxonomy and PII rules.
List destinations
curl https://api.brainstormrouter.com/v1/observability/xdr/destinations \
-H "Authorization: Bearer br_live_..."
Response includes id, name, type, enabled, filter_rules, and delivery counters. Secrets are redacted — apiKey, clientSecret, hecToken, workspaceKey, secretAccessKey (and snake-case variants) are never returned.
Create destination
curl -X POST https://api.brainstormrouter.com/v1/observability/xdr/destinations \
-H "Authorization: Bearer br_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Falcon Production",
"type": "crowdstrike",
"config": {
"client_id": "...",
"client_secret": "...",
"base_url": "https://api.crowdstrike.com"
},
"filter_rules": {
"include": ["auth.*", "cert.*", "data.*", "behavior.*"],
"min_severity": 3
}
}'
Update / delete
# Update — pass any subset of fields. filter_rules: null removes the rules.
curl -X PUT https://api.brainstormrouter.com/v1/observability/xdr/destinations/{id} \
-H "Authorization: Bearer br_live_..." \
-d '{"enabled": false}'
# Delete
curl -X DELETE https://api.brainstormrouter.com/v1/observability/xdr/destinations/{id} \
-H "Authorization: Bearer br_live_..."
Test connectivity
Sends one synthetic OCSF event to verify the destination accepts traffic. Returns HTTP 200 with { delivered: true } on success or { delivered: false, error: "..." } on failure (with the underlying adapter error code).
curl -X POST https://api.brainstormrouter.com/v1/observability/xdr/destinations/{id}/test \
-H "Authorization: Bearer br_live_..."
Stats and enable/disable
# Last 24h delivery counters: { sent, failed, dropped, last_delivery_at }
curl https://api.brainstormrouter.com/v1/observability/xdr/destinations/{id}/stats \
-H "Authorization: Bearer br_live_..."
# Toggle without deleting
curl -X POST https://api.brainstormrouter.com/v1/observability/xdr/destinations/{id}/enable \
-H "Authorization: Bearer br_live_..." \
-d '{"enabled": true}'
Bidirectional XDR risk push
Your XDR / SIEM pushes a per-agent risk score into BrainstormRouter via POST /v1/admin/xdr/risk-push. The next trust envelope synthesized for that agent reads the score into br_trust.xdr_risk. If the score is >= 0.7, the routing gate force-downgrades the agent to restricted-equivalent regardless of nominal tier.
Auth: Both push and clear require the platform.admin permission (same RBAC gate as every /v1/admin/* route).
Feature flag: Both endpoints return 403 feature_disabled unless XDR_BIDIRECTIONAL_ENABLED=1 is set on the gateway task. Default is OFF.
Field requirements: tenant_id and agent_id must be UUIDs; source is required (max 128 chars, logged for audit attribution); ttl_seconds is optional (handler default 86400 = 24h, max 2,592,000 = 30d).
curl -X POST https://api.brainstormrouter.com/v1/admin/xdr/risk-push \
-H "Authorization: Bearer <admin-key>" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "9f3b1e0c-c4a1-4a8e-9c8b-2e3f4a5b6c7d",
"agent_id": "1a2b3c4d-5e6f-7890-abcd-ef0123456789",
"risk_score": 0.83,
"source": "crowdstrike-falcon",
"ttl_seconds": 86400
}'
Append ?dry_run=true to verify connectivity without persisting; the response echoes { dry_run: true, would_set: { ... } }.
The score is stored at xdr:risk:{tenantId}:{agentId} in Redis with the configured TTL and auto-expires. To clear before the TTL elapses, issue a DELETE on the same path with the tenant_id + agent_id in the body:
curl -X DELETE https://api.brainstormrouter.com/v1/admin/xdr/risk-push \
-H "Authorization: Bearer <admin-key>" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "9f3b1e0c-c4a1-4a8e-9c8b-2e3f4a5b6c7d",
"agent_id": "1a2b3c4d-5e6f-7890-abcd-ef0123456789"
}'
The clear endpoint shares the same auth, feature flag, and ?dry_run=true behavior as the push endpoint.
Filter rules
Both generic webhook destinations and XDR destinations accept a filter_rules object that constrains what events that destination receives:
{
"filter_rules": {
"include": ["intelligence.*", "auth.*", "data.*"],
"exclude": ["intelligence.cache.*"],
"min_severity": 3
}
}
include— list of glob patterns. Empty / absent = match all event types.exclude— list of glob patterns. Applied afterinclude.min_severity— OCSF severity ID minimum (1=Informational, 2=Low,
3=Medium, 4=High, 5=Critical). Applied after type filters.
Glob matches [^.]+, so intelligence. matches intelligence.budget.exceeded (one segment after intelligence) but not intelligence.cache.eviction_pressure (two segments).