Getting Started
Observyze is a production-grade LLM observability platform. It monitors your AI applications in real-time, enforcing safety guardrails, capturing fine-grained prompt latency, tracking tokens, and managing circuit breakers.
Fast Track: Zero-Code Proxy Integration
RecommendedThe fastest way to get complete real-time tracing is through our Proxy Gateway. No custom libraries or wrappers required—just point your SDK’s baseURL to our gateway, and capture tokens, cost, latency, and payloads immediately.
Stuck? Test Your Setup
Paste your API key and run an instant diagnostic — we'll tell you exactly what's missing or misconfigured (invalid key, missing provider key, quota blocks, and more).
3-Step Foolproof Quickstart
Follow these three steps to begin tracing your LLM requests instantly.
Retrieve Your Observyze API Key
10 SecondsLog into the Observyze Console, navigate to Settings → API Keys, and generate a key. Every key has the prefix ob_ to ensure security identification.
ob_5f8b9e1c2a3d4e5f6g7h8i9j...Save Your Upstream Provider Keys
30 SecondsBecause our Proxy Gateway handles request redirection and circuit breakers, you must add your LLM provider keys (e.g. OpenAI Key, Anthropic Key) in the Observyze Dashboard under Settings → Provider Keys.
Update Your Client’s BaseURL & Start Tracing
60 SecondsReplace your SDK base URL (e.g. OpenAI's API URL) with the Observyze proxy. Set your authorization token to be your Observyze API Key. That’s it!
AI Agent Prompts
Are you using an AI assistant or editor (such as Cursor Composer, Windsurf, GitHub Copilot, ChatGPT, or Claude) to build your project? Copy these optimized prompts, paste them into your chat, and let the AI automatically inspect, refactor, and integrate Observyze for you.
Use this prompt in codebase-aware tools (like Cursor's Ctrl+I composer or Windsurf). It instructs the agent to search your files for OpenAI or Anthropic SDK usage and automatically apply proxy redirection:
Authentication
All requests to the Observyze Proxy Gateway or API endpoints require authentication using a project-specific API key. The key identifies which sandbox or production workspace receives the trace data.
Security Notice
API keys must always be stored securely on the server-side. Never expose your keys in front-end code, client-side requests (such as browser-based fetch), or public Git repositories.
API Key Format
Observyze uses a single, unified API key starting with the ob_ prefix to authenticate all requests, whether you are in development, testing, or production.
ob_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxob_ (first 3 chars)Use this single key across your local environments, pipelines, and production servers. Projects, limits, and scopes are managed automatically from your Observyze Console under settings.
Loading Your Keys Safely
Add your Observyze API key to an environment variable file (like .env or .env.local):
OBSERVYZE_API_KEY=ob_5f8b9e1c2a3d4e5f6g7h8i9jHow to safely access and construct authentication headers in common stacks:
// Access safely via process.env
const apiKey = process.env.OBSERVYZE_API_KEY;
if (!apiKey) {
throw new Error("Missing OBSERVYZE_API_KEY environment variable!");
}# Access safely via standard os library
import os
api_key = os.environ.get("OBSERVYZE_API_KEY")
if not api_key:
raise ValueError("Missing OBSERVYZE_API_KEY environment variable!")Making Authenticated HTTP Requests
Pass your key in the HTTP Authorization header prefixed by Bearer.
curl -X GET "https://api.observyze.com/api/v1/traces" \
-H "Authorization: Bearer ob_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json"API Reference
Detailed references for all standard REST API endpoints. You can query traces, invoke circuit breakers, update settings, retrieve cost limits, and fetch alert rules directly.
/api/v1/tracesList all traces with filtering and pagination
/api/v1/traces/:idGet a single trace with all spans
/api/v1/traces/:idSoft delete a trace with audit log
/api/v1/traces/:id/evaluateTrigger hallucination evaluation for a trace
/api/v1/traces/:id/replayRe-run a trace with modified inputs
/api/v1/ingestIngest traces from external systems
/api/v1/ingest/batchBatch ingest multiple traces
/api/v1/alerts/rulesList all alert rules
/api/v1/alerts/rulesCreate a new alert rule
/api/v1/optimization/circuit-breakerGet circuit breaker configuration
/api/v1/optimization/circuit-breakerUpdate circuit breaker configuration
/api/v1/bug-bounty/triggerManually trigger a bug bounty report for a specific trace
/api/v1/bug-bounty/historyGet history of all triggered bug bounty reports
/api/v1/bug-bounty/auto-detectScan for traces that meet auto-trigger failure criteria
/api/v1/analytics/cost/breakdownGet cost breakdown by model, project, or date range
/api/v1/analytics/cost/forecastGet AI-powered cost forecast for the current period
/api/v1/organizations/:orgIdGet organization details
/api/v1/audit-logsList audit logs with filtering
SDKs & Libraries
The Node.js/TypeScript SDK provides explicit local wrappers for OpenAI, Anthropic, Gemini, Vercel AI SDK, LangChain, and LlamaIndex call boundaries, plus custom spans. Other languages can send validated traces through the HTTP ingestion API; no official Python SDK is present in this repository.
Installation
Install our official package using your preferred package manager:
npm install @observyze/sdkInitialize Client
Configuration fields explained:
- apiKey: Your Observyze API key starting with
ob_... - organizationId: (Optional) Your target workspace organization ID
- projectId: (Optional) A logical tag to group logs (e.g.
frontend-ai-agent) - flushInterval: Latency delay in milliseconds before dispatching trace packages asynchronously
- debug: Toggle console outputs for debugging local integrations
import { ObservyzeClient } from '@observyze/sdk';
const nw = new ObservyzeClient({
apiKey: process.env.OBSERVYZE_API_KEY, // Pull from environment variable safely
organizationId: 'org_8j2k4m9p', // Group traces by org scope
projectId: 'customer-chat-agent', // Distinct tags for search filters
flushInterval: 5000, // Traces are grouped and sent every 5s asynchronously
debug: true // Print warnings and debug streams to stdout
});Instrument OpenAI
Use wrapOpenAI to seamlessly wrap your native OpenAI SDK instance. Behind the scenes, the SDK intercepts client completions calls, tracks metrics, and transparently routes the request to our secure Gateway Proxy without changing query formats.
import { ObservyzeClient, wrapOpenAI } from '@observyze/sdk';
import OpenAI from 'openai';
// 1. Initialize the Observyze client
const nw = new ObservyzeClient({ apiKey: process.env.OBSERVYZE_API_KEY });
// 2. Initialize standard OpenAI using normal configuration
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// 3. Wrap client to activate automatic tracing and circuit breakers
const tracedOpenAI = wrapOpenAI(openai, nw);
// 4. Use the wrapped client EXACTLY as normal. Telemetry collects automatically!
const response = await tracedOpenAI.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'What is the circuit breaker threshold?' }]
});Instrument Anthropic
Wrap your official Anthropic client with wrapAnthropic to securely capture Claude tokens, pricing, latency, and payloads.
import { ObservyzeClient, wrapAnthropic } from '@observyze/sdk';
import { Anthropic } from '@anthropic-ai/sdk';
// 1. Setup client
const nw = new ObservyzeClient({ apiKey: process.env.OBSERVYZE_API_KEY });
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
// 2. Wrap client
const tracedAnthropic = wrapAnthropic(anthropic, nw);
// 3. All completion requests will automatically stream metrics
const response = await tracedAnthropic.messages.create({
model: 'claude-3-5-sonnet-20241022',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Provide architectural feedback on credential sharding.' }]
});Custom Tracing & Non-LLM Telemetry
If your AI features include agentic workflows, database lookups, tool executions, or prompt chain evaluations, wrap them in Custom Spans to visualize the complete request timeline inside your dashboard.
import { ObservyzeClient, SpanType } from '@observyze/sdk';
const nw = new ObservyzeClient({ apiKey: process.env.OBSERVYZE_API_KEY });
// 1. Begin a root Trace grouping the entire request chain
const trace = await nw.startTrace({
name: 'agent-search-and-answer',
metadata: { userId: 'user_4a9c8f1e' }
});
// 2. Add custom Span tracking vector database latency
const dbSpan = await nw.startSpan({
name: 'pinecone-retrieval',
type: SpanType.DB,
input: { query: 'hybrid-cloud security guidelines', topK: 5 }
});
// Perform Pinecone / DB lookup logic here...
// Complete the Database span
await dbSpan.complete({
output: { matches_count: 5, score_avg: 0.92 },
metadata: { index: 'security-index-v2' }
});
// 3. Add custom Span tracking prompt evaluation
const llmSpan = await nw.startSpan({
name: 'claude-response-generation',
type: SpanType.LLM,
input: { model: 'claude-3-5-sonnet', promptTokens: 140 }
});
// Perform Claude query...
// Complete the LLM span
await llmSpan.complete({
output: { content: 'Answer text...' },
metadata: { tokens: 198 }
});
// 4. Complete the master trace to save to the Observyze backend
await trace.complete({ status: 'success' });Supported SDK Providers
SDK-level wrappers available in the published Node.js package:
Proxy Gateway
The Proxy Gateway lets you record LLM telemetry without installing our custom NPM/Python libraries. You simply adjust the LLM client configuration by setting its baseURL to Observyze’s edge endpoint. Everything else stays unchanged!
Supported Upstream Routing Endpoints
Route your requests through the appropriate Observyze gateway depending on your provider selection:
| Provider | SDK Base URL Endpoint |
|---|---|
| OpenAI | https://api.observyze.com/api/v1/proxy/openai/v1 |
| Anthropic | https://api.observyze.com/api/v1/proxy/anthropic |
| Google Gemini | https://api.observyze.com/api/v1/proxy/google |
| OpenRouter | https://api.observyze.com/api/v1/proxy/openrouter/v1 |
| Azure OpenAI | https://api.observyze.com/api/v1/proxy/azure/v1 |
| Cohere | https://api.observyze.com/api/v1/proxy/cohere/v1 |
| Mistral | https://api.observyze.com/api/v1/proxy/mistral/v1 |
| Groq | https://api.observyze.com/api/v1/proxy/groq/v1 |
OpenAI Gateway Setup
Change your client initialization to set baseURL to the Observyze proxy. Set your authorization header using your **Observyze Key** (loaded from environment variable OBSERVYZE_KEY). Make sure you have added your OpenAI api key to the dashboard settings under provider keys!
import OpenAI from 'openai';
const openai = new OpenAI({
// Load Observyze API key
apiKey: process.env.OBSERVYZE_KEY,
// Point baseURL to proxy gateway
baseURL: 'https://api.observyze.com/api/v1/proxy/openai/v1'
});from openai import OpenAI
import os
client = OpenAI(
# Load Observyze API key
api_key=os.environ["OBSERVYZE_KEY"],
# Point base_url to proxy gateway
base_url="https://api.observyze.com/api/v1/proxy/openai/v1"
)Anthropic Gateway Setup
Change your Anthropic client's baseURL to load through the proxy gateway:
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({
// Use your Observyze API Key
apiKey: process.env.OBSERVYZE_KEY,
// Change base endpoint to proxy gateway
baseURL: 'https://api.observyze.com/api/v1/proxy/anthropic'
});Google Gemini Setup
You can easily route requests from the new official google-genai SDK through the proxy by setting the base URL and Authorization header in the HTTP options:
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({
// Note: if you configured a BYOK key in Observyze, you can use a dummy key here.
apiKey: process.env.GEMINI_API_KEY,
httpOptions: {
baseUrl: 'https://api.observyze.com/api/v1/proxy/google',
headers: {
'Authorization': `Bearer ${process.env.OBSERVYZE_KEY}`
}
}
});from google import genai
from google.genai import types
import os
client = genai.Client(
api_key=os.environ.get("GEMINI_API_KEY"),
http_options=types.HttpOptions(
base_url="https://api.observyze.com/api/v1/proxy/google",
headers={"Authorization": f"Bearer {os.environ.get('OBSERVYZE_KEY')}"}
)
)Direct HTTP / cURL (Any Programming Language)
If you are using a programming language without official SDK support (such as Go, Rust, Ruby, or PHP), construct a raw POST request pointing to the gateway URL:
# OpenAI POST request
curl -X POST "https://api.observyze.com/api/v1/proxy/openai/v1/chat/completions" \
-H "Authorization: Bearer $OBSERVYZE_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Ping"}]
}'import requests
url = "https://api.observyze.com/api/v1/proxy/openai/v1/chat/completions"
headers = {
"Authorization": f"Bearer {os.environ['OBSERVYZE_KEY']}",
"Content-Type": "application/json"
}
payload = {
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Ping"}]
}
response = requests.post(url, headers=headers, json=payload)Architecture & Security
Understanding how telemetry and circuit breakers execute under the hood is critical for enterprise security audits. Here is a breakdown of our security posture.
1. Zero-Config URL Rewrite (Proxy Gateway)
The Proxy Gateway integration works by pointing your existing OpenAI or Anthropic SDK's baseURL (or base_url in Python) to Observyze. For example, instead of https://api.openai.com, you set it to https://api.observyze.com/api/v1/proxy/openai/v1. Your API key is replaced with your Observyze key (ob_...). The gateway intercepts every call, records it as a trace, then forwards the real request upstream — completely transparent to your application code.
2. Credential Sharding & Memory-Only Storage
To ensure provider safety, the SDK swaps headers securely:
- The SDK saves your original provider API key (e.g. OpenAI key).
- It overwrites the default
Authorizationheader with your **Observyze Key** to authorize proxy entry. - It moves the provider key into a dedicated, secure metadata header:
x-provider-key.
Ephemeral Upstream Credential Handling:
The value in x-provider-key is used by the gateway to authorize the upstream request and is not intentionally persisted in trace records. Keep request-header logging disabled or redacted in every proxy, load balancer, and APM layer.
3. Direct Provider Routing and Content Omission
If your data-governance policy restricts an additional gateway, disable proxy redirect and content capture together. Local deterministic redaction provides an additional layer but is not NER:
const nw = new ObservyzeClient({
apiKey: process.env.OBSERVYZE_API_KEY,
enableProxyRedirect: false,
enablePiiRedaction: true,
captureContent: false
});Evaluation & Safety
Run hallucination and safety evaluations, trigger custom trace replays, configure active circuit breakers, and run auto-detection systems.
Hallucination Evaluation
Evaluate traces for accuracy and context alignment. It returns a score from 0.00 (fully accurate) to 1.00 (completely hallucinated).
# Trigger check via REST API
curl -X POST "https://api.observyze.com/api/v1/traces/tr_abc123/evaluate" \
-H "Authorization: Bearer ob_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json"
# Example Evaluation Response
{
"success": true,
"score": 0.08,
"details": {
"reasoning": "The response perfectly aligns with Pinecone context retrieval facts.",
"evaluated_by": "mistralai/mistral-7b-instruct:free"
}
}Trace Replay
Re-run past traces with modified inputs. Perfect for testing new prompt versions, comparing output formatting, or evaluating model performance on historical test cases.
# Trigger replay via webhook execution
curl -X POST "https://api.observyze.com/api/v1/traces/tr_abc123/replay" \
-H "Authorization: Bearer ob_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-app.com/api/observyze-replay",
"modified_spans": [
{
"span_id": "span_9k2v",
"input": { "messages": [{"role": "user", "content": "Optimized prompt query text"}] }
}
]
}'Circuit Breaker Configuration
If model outputs trigger safety violations, hallucinate excessively, or generate critical failures consecutively, the Circuit Breaker trips to halt routing, protecting your application budget and UX.
# Update config via REST API
curl -X POST "https://api.observyze.com/api/v1/optimization/circuit-breaker" \
-H "Authorization: Bearer ob_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"thresholds": {
"hallucination_score": 0.60,
"safety_score": 0.50,
"consecutive_failures": 3,
"failure_window_minutes": 5
},
"action": "halt",
"cooldown_seconds": 60
}'Webhook Ingestion
The Observyze Webhook Ingest system allows any external tool, no-code platform, or custom backend to push trace data into Observyze using a simple HTTP POST request. This is an inbound integration — your system sends data to Observyze, and it appears in your dashboard as a trace.
Ingest Endpoint
Send a POST request to https://api.observyze.com/api/v1/ingest with your Observyze API key in the Authorization header. The endpoint auto-detects the payload format — a single event, a full trace with spans, or a batch of events.
Simple EventSend a single LLM call — name, input, output, model, tokens. Observyze wraps it in a trace automatically.
Full Trace (with spans)Send a complete trace object with a spans array for multi-step pipelines (agent chains, tool calls, etc.).
Batch IngestionSend up to 100 simple events with { events: [...] } or complete SDK traces with { traces: [...] }.
Example 1 — Simple Event
The simplest integration: just POST a JSON object describing a single LLM call. Observyze will automatically assign a trace_id and store the event.
curl -X POST "https://api.observyze.com/api/v1/ingest" \
-H "Authorization: Bearer ob_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer Support Reply",
"input": { "messages": [{"role": "user", "content": "How do I reset my password?"}] },
"output": { "content": "Go to Settings → Account → Reset Password." },
"model": "gpt-4o",
"status": "success",
"duration_ms": 843,
"tokens": { "input": 45, "output": 18, "total": 63 },
"cost": 0.00031,
"tags": ["support", "production"],
"user_id": "user_abc123"
}'
# Response:
{ "accepted": true, "trace_id": "nw_a4b8f2c1d3e5" }Example 2 — Batch Ingestion
Use POST /api/v1/ingest/batch to send up to 100 records. Use { events: [...] } for simple events or { traces: [...] } for complete SDK traces with spans.
curl -X POST "https://api.observyze.com/api/v1/ingest/batch" \
-H "Authorization: Bearer ob_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"name": "Product Q&A",
"input": { "messages": [{"role": "user", "content": "What is your return policy?"}] },
"output": { "content": "Returns are accepted within 30 days." },
"model": "gpt-4o-mini",
"status": "success",
"duration_ms": 510,
"tokens": { "input": 22, "output": 11, "total": 33 }
},
{
"name": "Sentiment Analysis",
"input": { "text": "The product is great but shipping was slow." },
"output": { "sentiment": "mixed", "score": 0.6 },
"model": "claude-3-haiku",
"status": "success",
"duration_ms": 280
}
]
}'
# Response:
{ "accepted": true, "count": 2, "trace_ids": ["nw_x1y2z3...", "nw_a4b5c6..."] }Mapped External Webhooks
A custom mapping receives arbitrary JSON at POST /api/v1/ingest/webhook/:mapping_id. Authenticate with the mapping-specific one-time key in X-Webhook-Key (or as a Bearer token), not with a project API key. The server pins organization and project ownership, applies the configured safe field transforms, redacts PII, enforces quota and deduplication, then uses the durable trace queue.
curl -X POST "https://api.observyze.com/api/v1/ingest/webhook/whm_xxxxx" \
-H "X-Webhook-Key: ob_wh_xxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "request": "hello", "response": "world", "latency_ms": 125 }'Mapping credentials are returned only at creation or regeneration time and are stored as bcrypt hashes. Legacy plaintext mapping credentials must be regenerated before use.
Simple Event — Field Reference
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | A human-readable label for this trace (e.g. "Customer Q&A"). |
| input | any | Yes | The input sent to the model — typically a messages array or a prompt string. |
| output | any | Yes | The model's response. Can be a string, object, or any JSON value. |
| model | string | No | The model name used (e.g. gpt-4o, claude-3-haiku). Used for cost estimates. |
| status | enum | No | success | error | timeout | running. Defaults to success. |
| duration_ms | number | No | How long the LLM call took in milliseconds. |
| tokens | object | No | { input, output, total } — token counts for cost tracking. |
| cost | number | No | Total cost of the call in USD (e.g. 0.00031). Auto-estimated if omitted. |
| tags | string[] | No | Labels for filtering in the dashboard (e.g. ["production", "support"]). |
| user_id | string | No | Your app's user ID — used for per-user analytics. |
| session_id | string | No | Groups multiple traces into a single conversation session. |
| metadata | object | No | Any additional key-value pairs you want to store with the trace. |
Error Handling
Observyze uses standard REST API error status codes. If a circuit breaker blocks a request, or credentials are invalid, we return explicit status details.
| HTTP Status | Error Name | Description / Solution |
|---|---|---|
| 400 | Bad Request | Invalid request format or missing required fields |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Insufficient permissions for this action |
| 404 | Not Found | Resource does not exist |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Error | Server error - contact support |
| 503 | Service Unavailable | System under maintenance |
Programmatic Exception Catching
When using our SDK wrappers or calling the proxy, catch exceptions to safely handle circuit breaker blockades:
try {
const response = await tracedOpenAI.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Execute query' }]
});
} catch (error: any) {
if (error.status === 429) {
console.warn("Observyze Circuit Breaker is active! Serving fallback response.");
// Fallback static prompt response logic here...
} else {
console.error("Standard SDK error caught:", error.message);
}
}Compliance Mode
Metadata-only mode is intended for strict data-governance environments. With proxy redirect disabled and content capture disabled, SDK-generated traces omit prompts, completions, arbitrary metadata, user/session identifiers, tags, and detailed errors before buffering. This is a technical privacy control—not a certification of GDPR, HIPAA, or SOC 2 compliance.
Two-Layer Privacy Architecture
Direct provider traffic + local content omission + server-side redaction.
Your Server
Content omitted locally
Observyze Cloud
Token counts, latency, cost
Configuration
Configure direct routing, content omission, and local redaction together:
import { ObservyzeClient } from '@observyze/sdk';
import OpenAI from 'openai';
const nw = new ObservyzeClient({
apiKey: process.env.OBSERVYZE_API_KEY,
// ── Compliance Mode ────────────────────────────────────────────────────────
// 1. Bypass the proxy gateway: LLM traffic goes directly from YOUR server
// to OpenAI/Anthropic instead of the Observyze proxy.
enableProxyRedirect: false,
// 2. Omit customer content locally. Inputs, outputs, arbitrary metadata,
// user/session identifiers, tags, and detailed errors are never buffered.
captureContent: false,
// 3. Keep deterministic redaction enabled as defense in depth for the
// remaining allowlisted operational fields and imported history.
// The SDK scrubs emails, SSNs, credit cards, JWTs,
// API keys, phone numbers, IP addresses, and sensitive JSON keys from
// all trace spans BEFORE they are asynchronously uploaded as telemetry.
enablePiiRedaction: true,
});
// Usage is identical — just wrap your client as normal.
const openai = nw.wrap(new OpenAI({ apiKey: process.env.OPENAI_API_KEY }));
// ✅ LLM call goes directly to OpenAI (not via Observyze proxy)
// ✅ Token counts, latency & cost metadata are still captured and uploaded
// ✅ Prompt and completion content are omitted locally before dispatch
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello!' }]
});PII Categories Redacted
The following patterns are scrubbed from all trace input and output payloads — both client-side (SDK) and server-side (proxy gateway) as a defense-in-depth measure.
| Category | Example Input | Redacted Output | Rule Type |
|---|---|---|---|
| Email Address | user@company.com | [EMAIL_REDACTED] | Value pattern |
| JWT Token | eyJhbGci... | [JWT_REDACTED] | Value pattern |
| Bearer Token | Bearer sk-abc123... | [AUTH_TOKEN_REDACTED] | Value pattern |
| OpenAI / API Key | sk-proj-abc123... | [API_KEY_REDACTED] | Value pattern |
| AWS Access Key | AKIAIOSFODNN7EXAMPLE | [AWS_KEY_REDACTED] | Value pattern |
| US SSN | 123-45-6789 | [SSN_REDACTED] | Value pattern |
| Credit Card | 4111 1111 1111 1111 | [CC_REDACTED] | Pattern + Luhn |
| Phone Number (US) | (555) 867-5309 | [PHONE_REDACTED] | Value pattern |
| Phone Number (Intl) | +44 20 7946 0958 | [PHONE_REDACTED] | Value pattern |
| IPv4 Address | 192.168.1.100 | [IP_REDACTED] | Value pattern |
| IPv6 Address | 2001:db8::ff00:42:8329 | [IP_REDACTED] | Value pattern |
| Passport JSON field | { "passport": "A12345678" } | { "passport": "[REDACTED]" } | Key-based rule |
| Sensitive JSON Key | { "password": "s3cr3t" } | { "password": "[REDACTED]" } | OWASP A02 |
Security Controls and Boundaries
SDK Content Omission
With enableProxyRedirect: false and captureContent: false, wrapped LLM traffic goes directly to your provider and SDK traces contain metadata only.
Defense-in-Depth Scrubbing
Shared deterministic redaction runs client-side before upload and server-side before persistence. Regex masking is not NER and cannot guarantee detection of names in arbitrary prose.
Controlled Audit Context
Security audit events may retain source IP and user-agent data for investigation. Treat these records as personal data and apply access, retention, and regional policies appropriate to your deployment.
Metadata-Only SDK Traces
Token usage, latency, provider/model identifiers, statuses, and span timing remain available when providers expose them. This boundary applies to SDK traces configured with captureContent: false; direct API callers must enforce the same policy.
What You Still Get in Compliance Mode
Metadata-only mode intentionally trades content-dependent analysis for stronger data minimization.
Configurable Retention & Cold Archival
The S3-compatible archival worker moves trace payloads older than each organization's configured retention period to object storage. Retention requirements vary by data type, jurisdiction, and customer policy; configure and validate them with your compliance team.
Traces older than the organization retention policy are uploaded as compressed NDJSON (.jsonl.gz) before hot payload fields are removed.
Prompt and completion fields are removed from archived hot records while identifiers and operational metadata remain searchable. No latency guarantee is implied.
Every uploaded batch has a JSON manifest with tenant ID, timestamps, retention policy, trace count, and object key. Bucket immutability and encryption must be configured at the storage provider.
Audit Manifest Schema (manifest_*.json)
{
"archive_id": "archive_1787309046000",
"organization_id": "org_a4b8f2c1d3e5",
"archived_at": "2026-08-21T10:44:06.000Z",
"retention_days": 30,
"total_traces": 500,
"batch_file": "traces/org_a4b8f2c1d3e5/2026-08-21/batch_1787309046000.jsonl.gz"
}Enterprise: Bring Your Own Storage Configuration
To stream cold archives directly into your organization's private AWS S3, Cloudflare R2, or Google Cloud Storage bucket, configure the following environment variables in your deployment:
| Variable | Example / Default | Description |
|---|---|---|
| COLD_STORAGE_S3_BUCKET | my-corp-observability-archive | Target S3 / R2 / GCS bucket name. |
| COLD_STORAGE_S3_REGION | us-east-1 | Target cloud region. |
| COLD_STORAGE_S3_ACCESS_KEY | AKIAIOSFODNN7EXAMPLE | IAM access key with s3:PutObject and s3:GetObject permissions. |
| COLD_STORAGE_S3_SECRET_KEY | wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY | IAM secret access key. |
| COLD_STORAGE_S3_ENDPOINT | https://<account_id>.r2.cloudflarestorage.com | Optional endpoint for Cloudflare R2, MinIO, or custom S3-compatible storage. |
| COLD_STORAGE_BATCH_SIZE | 500 | Maximum traces uploaded and committed per worker batch. |
Cold Storage REST Endpoints
/api/v1/cold-storage/statusReturns S3 connection health, bucket name, and active retention policy.
/api/v1/cold-storage/archiveEnqueues an asynchronous BullMQ archival job (Admin only).
System Limitations
Observyze is designed with transparency. These are the known constraints and design boundaries of the current system.
Evaluation Throughput
Free tier capped at 1,000 evaluations per day per organization. Pro tier has unlimited evaluations with rate limits at 100 evaluations per minute.
NLI Model Scope
The NLI fast-path uses proprietary cross-encoders and only evaluates spans with grounding context (retrieval, RAG, tool, or LLM input). Spans without context fall back to LLM consensus evaluation.
Calibration Data Requirements
The auto-tune system requires at least 3 human-corrected evaluations per evaluation type per organization within a 30-day window to compute meaningful metrics. Insufficient data results in skipped calibration.
PII Redaction Coverage
PII redaction covers email, phone, SSN, credit card, API key, auth token, and IP address patterns. Custom patterns can be configured per organization through the organization settings.
Consensus Evaluation
LLM consensus evaluation uses a proprietary multi-model AI pipeline. In rare cases where models are unavailable, it falls back to a hardcoded fallback chain. Evaluation quality depends on available model diversity.
Circuit Breaker Cooldown
When tripped, circuit breakers enforce a minimum 60-second cooldown before allowing requests through. Low-confidence evaluations (>0.4) de-escalate from "halt" to "alert" mode.
Guides & Tutorials
Step-by-step developer tutorials for setting up intermediate and advanced configurations in Observyze.
Setting Up Your First Project
Create your organization scope, initialize project channels, and connect provider credentials.
Configuring Alert Rules
Set up strict cost, latency, and tokens thresholds with custom Slack notifications.
Managing Team Members
Invite engineers, configure fine-grained role scopes, and audit access logs.
Understanding Cost Analytics
Drill down into per-token models, calculate monthly spend, and audit team billing.
Implementing Circuit Breakers
Create fallback paths and trigger immediate halts for malfunctioning models.
Prompt Hub & Versioning
Establish a central prompt registry, run testing variants, and review history.
Setting Up SSO
Deploy enterprise-grade SAML or OIDC single sign-on parameters securely.