Skip to content

Docs

PRISM Documentation

Trace, score, and guard your AI agents in production. Send your first trace in five minutes.

Platform: prism.blockconvey.com · Support: Tech@blockconvey.com

Contents

Introduction

What PRISM Does

PRISM is an observability platform for AI agents. Your application sends PRISM a record of each exchange it has with a model. PRISM stores that record, scores it automatically, groups it into conversations and runs, watches it for the failures you care about, and tells you when something changes.

Everything starts from one HTTP call. Frameworks, the SDK, and the proxy are conveniences layered on top of it, so no integration path can do something the API cannot.

Core Concepts

TermWhat it is
ProjectThe isolation boundary. API keys, traces, guardrail rules, and alert rules all belong to exactly one project. Use one project per environment.
TraceOne exchange: the input messages, the agent's reply, and the model, latency, and token counts around it. The unit you send and the unit PRISM scores.
SessionTraces that share a session_id, assembled into one conversation. Send the same value for every turn of a conversation.
Agent runThe trajectory inside a single run: each model call, tool call, retrieval, and handoff. Produced automatically from spans when you use the SDK.
SpanOne step inside a run. The framework handlers emit these; the HTTP endpoint does not.
AgentIdentified by the agent_id you send. Filters traces, scopes alert rules, and populates Model Inventory.

Quickstart

Create an account at prism.blockconvey.com/signup. Signing up creates your organization and your first project. No invitation is needed.

1. Get Your Credentials

You need three values. Take the project ID from Settings → Project, and create a key on the API keys page.

bash
# .env  --  never commit this file
PRISMTRACE_HOST=https://prism.blockconvey.com
PRISMTRACE_PROJECT_ID=00000000-0000-0000-0000-000000000000
PRISMTRACE_API_KEY=pt-sk-...
bash
echo '.env' >> .gitignore

2. Send a Trace

Every integration eventually does this. Run it once from your terminal to prove the credential works before wiring anything into your application.

bash
curl -sS -X POST "$PRISMTRACE_HOST/api/traces" \
  -H "Content-Type: application/json" \
  -H "X-PRISMtrace-Key: $PRISMTRACE_API_KEY" \
  -d '{
    "project_id":     "'"$PRISMTRACE_PROJECT_ID"'",
    "model":          "claude-sonnet-4-6",
    "input_messages": [{"role": "user", "content": "What loan rates do you offer?"}],
    "output_message": "Our personal loan rates currently start at 7.9% APR.",
    "latency_ms":     420,
    "session_id":     "conversation-1",
    "agent_id":       "loan-assistant"
  }'

A 200 returns the stored trace, including its id and computed cost_usd. Open Traces and it is there.

3. Confirm It Landed

An empty dashboard has several possible causes that look identical from the outside. Connection health tells them apart, and the same information is available over the API.

StageMeans
Credential createdThe project has an API key. Without one, nothing is accepted whatever your app sends.
SDK installedSomething has proved it holds a working key. Separates "installed but sending nothing" from "not installed".
Live event receivedReal traffic is arriving. If this is stuck while the credential is fine, your integration is not running where you think it is.
Trace normalizedTraces carry a shared session_id and have been assembled into runs. Stuck here means you are not sending one.
Analysis readyAutomatic scoring has caught up. Lagging here is normal and is not a setup failure.

Programmatically:

bash
curl -sS "$PRISMTRACE_HOST/api/setup-doctor?project_id=$PRISMTRACE_PROJECT_ID" \
  -H "X-PRISMtrace-Key: $PRISMTRACE_API_KEY"

Read live_connected and blocked_step. From a Python project, python -m prismtrace.verify does the same thing.

Integrations

Choosing a Path

Three ways in. You need one.

PathYou changeYou captureUse when
Python SDKAttach a handler to your frameworkFull trajectories: model calls, tool calls, retrieval, handoffs, errorsYour app is Python and uses LangChain, LangGraph, Google ADK, LiteLLM, or the OpenAI Agents SDK.
Zero-code proxyOne base URL in your client configModel-level: prompts, completions, latency, tokens, plus inline guardrailsYou call Anthropic, OpenAI, or Gemini directly, in any language.
HTTPOne POST after each responseOne trace per exchange, plus whatever metadata you attachAnything else: TypeScript, Go, Java, or a framework the SDK does not cover.

Python SDK

The distribution is prismtrace-sdk; the import package is prismtrace. Install one, import the other.

bash
pip install "prismtrace-sdk>=0.4.0"

LangChain

python
import os
from prismtrace import PRISMtraceCallbackHandler
from langchain_anthropic import ChatAnthropic

handler = PRISMtraceCallbackHandler(
    api_key=os.environ["PRISMTRACE_API_KEY"],
    project_id=os.environ["PRISMTRACE_PROJECT_ID"],
    host=os.environ["PRISMTRACE_HOST"],
    agent_name="loan-assistant",
    session_id="conversation-1",   # one value per conversation
)

llm = ChatAnthropic(model="claude-sonnet-4-6", callbacks=[handler])
# ... run your chain or agent ...
handler.flush()

LangGraphwrap_langgraph injects the callbacks on invoke and stream, so you do not repeat the config at every call site.

python
import os
from prismtrace import PRISMtraceLangGraphHandler, wrap_langgraph

handler = PRISMtraceLangGraphHandler(
    api_key=os.environ["PRISMTRACE_API_KEY"],
    project_id=os.environ["PRISMTRACE_PROJECT_ID"],
    host=os.environ["PRISMTRACE_HOST"],
    agent_name="my-graph",
    session_id="graph-run-1",
)

graph = wrap_langgraph(compiled_graph, handler)
graph.invoke({"messages": [("user", "hello")]})
handler.flush()

Google ADK — multi-agent handoffs are recorded as handoff steps, so delegation between sub-agents shows in the trajectory instead of collapsing into one opaque run.

python
import os
from prismtrace import PRISMtraceADKAdapter
from google.adk.agents import LlmAgent

adapter = PRISMtraceADKAdapter(
    api_key=os.environ["PRISMTRACE_API_KEY"],
    project_id=os.environ["PRISMTRACE_PROJECT_ID"],
    agent_name="my-adk-agent",
)

agent = LlmAgent(
    model="gemini-2.0-flash",
    instruction="You are a helpful assistant.",
    before_model_callback=adapter.before_model,
    after_model_callback=adapter.after_model,
    before_tool_callback=adapter.before_tool,
    after_tool_callback=adapter.after_tool,
    before_agent_callback=adapter.before_agent,
    after_agent_callback=adapter.after_agent,
)

LiteLLM — one call at startup traces every model LiteLLM routes to, through a single hook.

python
import os, litellm
from prismtrace import install_litellm

install_litellm(
    api_key=os.environ["PRISMTRACE_API_KEY"],
    project_id=os.environ["PRISMTRACE_PROJECT_ID"],
)

response = litellm.completion(
    model="gpt-4o",
    messages=[{"role": "user", "content": "hello"}],
)

OpenAI Agents SDK

python
import os
from agents import Agent, Runner
from prismtrace import install_openai_agents

install_openai_agents(
    api_key=os.environ["PRISMTRACE_API_KEY"],
    project_id=os.environ["PRISMTRACE_PROJECT_ID"],
)

agent = Agent(name="my-agent", instructions="...")
result = await Runner.run(agent, "hello")

TypeScript and JavaScript

Instrument your chat handler, or the completion callback of generateText / streamText, so each turn emits one trace. On serverless, await the call so the function is not frozen mid-request.

typescript
const HOST = process.env.PRISMTRACE_HOST!;
const API_KEY = process.env.PRISMTRACE_API_KEY!;
const PROJECT_ID = process.env.PRISMTRACE_PROJECT_ID!;

export async function emitTrace(
  input: string,
  output: string,
  opts: { model: string; latencyMs: number; sessionId?: string },
) {
  const res = await fetch(HOST + "/api/traces", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-PRISMtrace-Key": API_KEY,
    },
    body: JSON.stringify({
      project_id: PROJECT_ID,
      model: opts.model,
      input_messages: [{ role: "user", content: input }],
      output_message: output,
      latency_ms: opts.latencyMs,
      session_id: opts.sessionId,
    }),
  });
  if (!res.ok) {
    throw new Error("PRISM ingest " + res.status + ": " + (await res.text()));
  }
}

Zero-Code Proxy

Point your existing provider client at PRISM instead of the provider. Nothing is imported and no call site changes. PRISM forwards the call, records it, and runs your guardrails in both directions. It adds one network hop, roughly 5 to 15 ms depending on region.

Three providers are proxied. Each client wants the base URL in a slightly different shape.

python
import anthropic, os

client = anthropic.Anthropic(
    api_key=os.environ["ANTHROPIC_API_KEY"],
    base_url="https://prism.blockconvey.com/proxy/anthropic",
    default_headers={"X-PRISMtrace-Key": os.environ["PRISMTRACE_API_KEY"]},
)

# OpenAI  ->  base_url="https://prism.blockconvey.com/proxy/openai/v1"
# Gemini  ->  client_options={"api_endpoint": "https://prism.blockconvey.com/proxy/gemini"}

Azure AI Foundry uses the OpenAI proxy route with your resource passed as an x-azure-endpoint header. AWS Bedrock does not use the proxy: it connects with stored AWS credentials from the Connectors page.

Voice Agents

A voice agent has no LLM call site to wrap, so PRISM hooks the voice platform. Each ElevenLabs call becomes one trajectory: caller speech is a speech-to-text step, the agent reply is a text-to-speech step. Transcripts are scrubbed for PII on the server before storage, and audio is never sent to or stored by PRISM.

  • Post-call webhook. No code. Point ElevenLabs at the webhook URL on the

connector card and subscribe to post_call_transcription only. Do not enable post_call_audio; PRISM rejects it. Store the ElevenLabs signing secret on the connector so deliveries are verified against your project.

  • Live tracing. Calls appear while they are still in progress.
python
import os
from elevenlabs.client import ElevenLabs
from elevenlabs.conversational_ai.conversation import Conversation
from elevenlabs.conversational_ai.default_audio_interface import DefaultAudioInterface
from prismtrace import PRISMtraceVoiceTracer

tracer = PRISMtraceVoiceTracer(
    api_key=os.environ["PRISMTRACE_API_KEY"],
    project_id=os.environ["PRISMTRACE_PROJECT_ID"],
    agent_name="Support line",
)

conversation = Conversation(
    ElevenLabs(api_key=os.environ["ELEVENLABS_API_KEY"]),
    AGENT_ID,
    requires_auth=True,
    audio_interface=DefaultAudioInterface(),
    **tracer.callbacks(),
)

conversation.start_session()
tracer.finalize(conversation.wait_for_session_end())

Warehouses and Export

Connect Snowflake or Databricks from the Connectors page with stored warehouse credentials, then sync on demand. Data Export downloads traces, scores, annotations, conversations, and alerts as CSV. Import Traces back-fills history from an existing log so you are not starting from an empty dashboard.

API Reference

Base URL: https://prism.blockconvey.com

Authentication

Machine callers authenticate with the X-PRISMtrace-Key header. This is not a bearer token: Authorization: Bearer carries dashboard sessions and will be rejected for an API key.

bash
X-PRISMtrace-Key: pt-sk-...

Keys carry scopes. Give an application only what it needs.

ScopeAllows
ingestSending traces and spans. This is what your application should carry.
readReading traces, analyses, and balances back out.
operateTriggering actions that spend credits.

A key can be rotated with a grace period, so the old one keeps working while you roll out the new one, then revoked. Both are on the API keys page.

Create a Trace

POST https://prism.blockconvey.com/api/traces

json
{
  "project_id": "00000000-0000-0000-0000-000000000000",
  "model": "claude-sonnet-4-6",
  "input_messages": [
    { "role": "user", "content": "What loan rates do you offer?" }
  ],
  "output_message": "Our personal loan rates currently start at 7.9% APR.",
  "latency_ms": 420,
  "token_count_input": 45,
  "token_count_output": 180,
  "session_id": "conversation-1",
  "user_identifier": "user-4521",
  "agent_id": "loan-assistant",
  "agent_name": "Loan Assistant",
  "metadata": { "source": "production" }
}
FieldTypeRequiredDescription
project_idstringYesProject UUID, from Settings → Project.
modelstringYesModel name. Drives per-model cost and latency breakdowns.
input_messagesarrayYesObjects of {role, content}.
output_messagestringYesThe agent reply.
latency_msintYesResponse time. Send 0 if you are not measuring it.
session_idstringNoGroups traces into one conversation or run. Without it, traces never assemble into a session.
agent_idstringNoStable agent identifier. Matched by Model Inventory and agent-scoped alert rules.
agent_namestringNoDisplay name for the agent.
user_identifierstringNoYour identifier for the end user.
trace_idstringNoYour own id for this trace. Re-sending the same one returns the existing trace instead of duplicating it.
token_count_inputintNoDefaults to 0. Used for cost.
token_count_outputintNoDefaults to 0. Used for cost.
metadataobjectNoFree-form. Filterable in the dashboard.

Returns 200 with the stored trace: its id, the resolved cost_usd, and the session_id it was filed under.

Diagnostics

EndpointPurpose
POST /api/setup-doctor/handshakeProves a credential and optionally stores one test trace. Always authenticates and returns a specific reason on failure. Body: {project_id, send_test_trace}.
GET /api/setup-doctorReports pipeline state for a project: live_connected, per-stage status, and blocked_step. Query: project_id.

Usage and Credits

EndpointReturns
GET /api/credits/summaryBalance, per-source breakdown, current cycle, renewal date, and whether spending is paused.
GET /api/credits/ledgerEvery credit movement, with the capability that caused it.
GET /api/credits/catalogThe price of every metered action, and what one unit buys.
GET /api/entitlementsYour plan, its features, its numeric limits, and how each limit is enforced.
GET /api/entitlements/usageCurrent usage against each limit.

Errors and Limits

StatusMeaningWhat to do
401Missing or invalid credential. The response body names which.Check the header name and that the key was not revoked.
403The key is valid but belongs to a different project, or lacks the scope for this call.Use the project ID named in the message, or a key with the right scope.
402Either the credit balance cannot cover this action, or the feature is not on your plan.Read error: insufficient_credits carries the price and balance; plan_limit_reached names the limit.
404No such project.Re-check the project ID.
429Rate limited. Ingest allows 200 requests per minute.Back off and retry, or batch.

Platform

Traces, Sessions, and Runs

Click any trace for the full conversation, the automatic analysis, the trajectory steps, and any guardrail flags. Above the list, Sessions groups traces sharing a session_id so a conversation reads end to end, and Agent Runs shows the trajectory inside a single run: which model was called, which tools fired, where a handoff happened, and where it failed.

Model Inventory fills itself from the agent_id and model on your traces. There is nothing to register by hand; send a trace and the agent appears, with trace count, average latency, last activity, and provider. Sending a stable agent_id is what stops one agent splitting into several entries.

Automatic Scoring

Every trace is analysed on arrival. This costs no credits and happens whether or not you ask for it.

ScoreRangeWhat it measures
Customer satisfaction0–100How satisfied the user would likely feel with this response. Alert rules read this as compliance_score.
Response quality0–100Accuracy, helpfulness, and clarity of the reply.
Intent detectedlabelWhat the user was trying to accomplish. Filterable and groupable.
Flagged for reviewbooleanSet when either score is below 40, the reply looks like a hallucination, the user seems very frustrated, or the conversation contradicts itself. Carries a one-line reason.

PRISM also detects the industry of a conversation and applies extra checks on top: rate promises and regulated-activity flags for financial conversations, PHI exposure and unsafe medical advice for healthcare, and privilege risk for legal.

Guardrails

Every rule has an action, flag or block, and takes effect on save with no deployment step. Ten rule types are available.

Rule typeCatchesSeverity
PII / PHI DetectionPersonally identifiable and protected health informationCritical
Prompt InjectionAdversarial prompts overriding agent instructionsCritical
Content ModerationInappropriate or policy-violating contentHigh
Toxicity DetectionToxic and harmful language in responsesHigh
Secrets DetectionAPI keys, passwords, and other secrets in outputHigh
Code Safety LinterUnsafe patterns in generated codeMedium
SQL SanitizerSQL injection patterns in user inputMedium
Regex Pattern MatchYour own patterns: account numbers, internal codesMedium
Off-Topic DetectionQueries outside the agent scope, optionally grounded in your Knowledge BaseMedium
Language RestrictionInput or output outside the languages you allowMedium

Where to start

  1. PII / PHI on flag. Watch what it catches on your own traffic for a few days, then switch to block once you trust it.
  2. Prompt Injection on block. There is no legitimate reason for a user to override your agent instructions.
  3. Secrets Detection on block if your agent can see configuration, infrastructure, or code.

Alerts

A rule is a metric, a condition, a threshold, and a severity, optionally scoped to one agent. Give it a notification email and PRISM writes there when the rule fires. Fired alerts can be resolved or dismissed, and repeated firings are grouped into patterns so a recurring problem reads as one thing rather than forty. Alerts are available on Free and Builder alike.

MetricMeasuresTypical rule
latencyResponse time of the trace, in millisecondsAbove 5000
compliance_scoreThe customer-satisfaction score from automatic analysisBelow 60
error_ratePercentage of traces in the trailing hour with no outputAbove 5
traces_per_hourTrace volume in the trailing hourBelow 1, to catch an agent that has gone silent
guardrail_blocksGuardrail blocks in the windowAbove 10, to catch an attack or a bad rule
evaluation_failedTraces automatic analysis could not evaluateAbove 0

Root Cause and Remediation

Root Cause clusters failing traces into recurring problems and traces each back toward the prompt or code responsible, rather than leaving you to read failures one at a time. Remediation turns those clusters into concrete recommendations. Agent Intelligence sits above both, summarising a window of traffic in prose and naming the failure themes inside it.

Plans and Credits

Two separate things govern what your account can do. Plan limits are capacity: how much you can store and for how long. Credits meter the AI actions you deliberately trigger. Neither ever hides data you have already captured.

Free and Builder

Free is the complete core product, not a trial. Traces, sessions, agent runs, automatic scoring, alerts, root cause, remediation, Knowledge Base, Model Inventory, connectors, and export all work on Free. Builder raises the ceilings and adds three capabilities: Guardrails, the Evaluators Hub with its annotation queues, and the expanded Model Inventory.

FreeBuilderAt the ceiling
Traces per month25,000250,000Counted, warned about at 80% and 100%. Traces are still stored.
Distinct models520Counted and warned about. Traces are still stored.
Data retention14 days90 daysOlder traces stop appearing in reads. Nothing is refused on write.
Team members15Adding a member past the ceiling is refused.
Knowledge Base docs50500Further uploads are refused.
ProjectsUnlimitedUnlimitedNo ceiling. Use one project per environment.
Credits per cycle100500New AI actions pause. See below.

Live usage against each limit, and how each one is actually applied, is on Settings → Billing and usage, or over the API at GET /api/entitlements/usage.

Credits

A credit is the unit for AI work you ask PRISM to perform. Your plan grants an allowance once per rolling 30-day cycle, anchored to the date your organization was created rather than to the calendar month, so your cycle renews on your own date. New organizations also get a one-time welcome grant of 100 credits, and top-up packs of 100 can be bought at any time. Unused allowance carries over up to one full allowance, so an idle account does not accumulate indefinitely.

Free

Anything the platform does on its own. Trace ingest, viewing traces, the automatic per-trace analysis and its scores, trajectory assembly, regulatory classification, Knowledge Base processing, guardrail checks, dataset and evidence exports, and the onboarding and integration assistants. Free allows 25,000 traces against a 100-credit allowance, so metering automatic analysis would exhaust a cycle before you had taken a single action.

Metered

Actions you deliberately trigger. Prices follow one ladder: 1 for a single judgement, 2 for a recommendation, 5 for a multi-pass or report-sized job.

ActionCredits
Re-run analysis on a trace, including each trace in a back-fill1 per trace
Agent Intelligence narrative1, once per project per day
Generate a test scenario1
Prompt improvement suggestion2
Remediation recommendation2
Analyse an uploaded document against a control2
Generate test cases from an evaluation dataset2
Run an evaluator task, or an experiment5
Root-cause engine run over a project5
Root-cause fix attempt: patch, replay, and pull request5
Scenario blueprint or executive report5

At a zero balance

New AI actions pause, and nothing else does. Trace capture continues within your plan limits, existing data stays fully readable, automatic per-trace analysis keeps running, and guardrails and alerts keep working. An action you cannot afford returns 402 with the price and your balance, so your own tooling can handle it. There is no automatic overage and no auto top-up: the balance cannot go below zero without you buying more.

Security

  • Keys live in the environment. A .env file locally, your platform secret

manager in production. Never hardcode a key, never commit one.

  • Send the key as a header. Use X-PRISMtrace-Key. The deprecated body field

puts your credential into request logs and payload captures.

  • Use the narrowest scope. An application that only sends traces should carry

an ingest key. It cannot then read your data back or spend credits.

  • Rotate, do not swap. Rotation issues a new key while the old one keeps

working for a grace period. Roll out, then revoke.

  • One project per environment. Dev, staging, and production each get their own

project and keys, so revoking one never touches the others.

  • Keys are shown once. PRISM stores only a hash. If a key is lost, rotate it.
  • Voice audio is never stored. ElevenLabs transcripts are PII-scrubbed

server-side before storage, and audio is never sent to PRISM at all.

Troubleshooting

SymptomCauseFix
Dashboard is empty after integratingSeveral causes look identical from outside.Open Connection health. It names the stage that is stuck.
401 "No credential was sent"The header is missing, or the variable is unset in that environment.Send X-PRISMtrace-Key. Do not switch to Bearer.
401 "does not look like a key"A project ID or an unexpanded shell variable was pasted in place of the key.Use the pt-sk- value.
403 naming a different projectThe key and the project_id are from different projects.Use the project ID in the message, or a key from the right project.
Traces arrive but no conversationsNo shared session_id, so nothing assembles.Send one session_id per conversation.
One agent appears as severalagent_id changes between runs.Send a stable agent_id, not a generated one.
Scores are missing on recent tracesAnalysis lags ingest.Wait. This is not a setup failure and costs no credits.
402 on an action you expected to workEither a zero credit balance or a Builder-only feature.Read error in the body: it distinguishes the two.
A LangChain integration sends nothingCallbacks were never attached, or the process exited before a flush.Pass callbacks=[handler] and call handler.flush().
Looking for the npm packageThere is not one.Use the HTTP endpoint.

Reference

ItemValue
Platformhttps://prism.blockconvey.com
API base URLhttps://prism.blockconvey.com
Ingest endpointPOST /api/traces
AuthenticationX-PRISMtrace-Key header. Not a bearer token.
Key formatpt-sk-…, shown once at creation
Required fieldsproject_id, model, input_messages, output_message, latency_ms
Groups a conversationsession_id
Rate limit200 requests per minute
Python SDKpip install prismtrace-sdk, then import prismtrace
JavaScript SDKNone. Use the HTTP endpoint.
Proxy routes/proxy/anthropic, /proxy/openai/v1, /proxy/gemini
Project IDSettings → Project
PlansFree and Builder
SupportTech@blockconvey.com