veriproof-sdk
The core Python SDK for VeriProof. Handles OpenTelemetry configuration, session-level governance tracing, batch export with Merkle verification, and circuit-breaker transport resilience.
Install:
pip install veriproof-sdkQuick start
import os
from veriproof_sdk import VeriproofClientOptions, configure_veriproof
# Call once at application startup
configure_veriproof(
VeriproofClientOptions(
api_key=os.environ["VERIPROOF_API_KEY"],
application_id="my-ai-app",
),
service_name="my-ai-app",
set_global=True, # Registers as the global TracerProvider
)
# All OTel spans created after this call are exported to VeriProofconfigure_veriproof
Sets up a TracerProvider with a VeriproofSpanExporter and optionally registers it as the global OTel provider.
def configure_veriproof(
options: VeriproofClientOptions,
service_name: str,
set_global: bool = False,
existing_provider: TracerProvider | None = None,
) -> tuple[TracerProvider, VeriproofSpanExporter]:| Parameter | Type | Description |
|---|---|---|
options | VeriproofClientOptions | SDK configuration (see below) |
service_name | str | OTel service name attribute on all spans |
set_global | bool | If True, calls opentelemetry.trace.set_tracer_provider() |
existing_provider | TracerProvider | None | Attach to an existing provider instead of creating one |
Returns (TracerProvider, VeriproofSpanExporter).
VeriproofClientOptions
VeriproofClientOptions(
# ── Required (or via environment variables) ─────────────────
api_key: str | None = None,
# Sent as the X-API-Key header. Falls back to VERIPROOF_API_KEY env var.
application_id: str | None = None,
# Logical name registered in the portal. Falls back to VERIPROOF_APPLICATION_ID.
# ── Network ─────────────────────────────────────────────────
endpoint: str = "https://veriproof-api.rjrlabs.com",
# Ingest API base URL. Override for Enterprise Federated deployments.
# Falls back to VERIPROOF_ENDPOINT env var.
http_timeout_seconds: float = 30.0,
allow_insecure_endpoint: bool = False,
# Must be True to allow http:// endpoints (disabled by default).
headers: Mapping[str, str] = {},
# Extra headers merged into every outbound request.
api_key_provider: Callable[[], str] | None = None,
# Called at request time to retrieve the API key. Use for dynamic rotation.
# ── Circuit breaker ─────────────────────────────────────────
circuit_breaker_failure_threshold: int = 3,
# Consecutive failures to open the circuit.
circuit_breaker_reset_timeout_seconds: float = 30.0,
# Seconds the circuit stays open before entering half-open.
# ── Buffer ──────────────────────────────────────────────────
buffer_capacity: int = 500,
# Max payloads buffered while the circuit is open. Oldest dropped when full.
# ── Content capture ─────────────────────────────────────────
enable_content_capture: bool = False,
# Capture gen_ai.* message fields and retrieval documents in exported spans.
# Keep False (default) for GDPR compliance and data minimization.
content_capture_size_threshold_bytes: int = 65_536,
# Max byte length of a single content field before truncation.
max_document_content_bytes: int = 4_096,
# Max byte length of a captured retrieval document.
redacted_attributes: tuple[str, ...] = (),
# OTel attribute keys to redact. Supports prefix.* glob.
# Example: ("gen_ai.input_messages",)
# ── Defaults ────────────────────────────────────────────────
default_transaction_type: str | None = None,
# Applied to sessions that do not call .with_transaction_type().
)Class method for sandbox:
opts = VeriproofClientOptions.sandbox(
api_key="vp_cust_sandbox_...",
application_id="my-app",
)VeriproofSession
Fluent session builder. Wraps a logical AI transaction with governance context.
session = (
VeriproofSession(application_id="my-app")
.with_session_id("session-001") # Unique session identifier
.with_intent("loan_eligibility_check") # What the AI was asked to do
.with_transaction_type("credit_review") # Business transaction type
)
async with session:
# ... add steps, chat turns, decision ...
passMethods
| Method | Description |
|---|---|
.with_session_id(id: str) | Set the session identifier (defaults to a UUID if not called) |
.with_intent(intent: str) | Set the session-level intent string |
.with_transaction_type(type: str) | Classify the transaction type |
.add_step(name, output=None, tags=None) | Add a discrete step (retrieval, tool call, etc.) |
.add_chat_turn(prompt, response, model) | Log an LLM prompt/response pair |
.set_decision(context: DecisionContext) | Attach a structured decision record |
.set_outcome(outcome, risk_level=None) | Record the session outcome and risk level |
.set_metadata(key, value) | Attach arbitrary key-value governance metadata |
DecisionContext
# Named options decision (recommended for compliance evidence)
ctx = DecisionContext.with_options(
label="Loan approval",
options=["approve", "deny", "manual_review"],
selected="approve",
rationale="Credit score 718 exceeds minimum 680 threshold.",
confidence=0.91,
)
# Score-based decision
ctx = DecisionContext.with_score(
label="Fraud risk score",
score=0.23,
threshold=0.50,
outcome="pass",
)StepTags
Pre-defined tag sets that classify step types for compliance dashboards:
| Tag method | Purpose |
|---|---|
StepTags.retrieval() | Data retrieval (RAG, database lookup, API call) |
StepTags.generation() | LLM generation step |
StepTags.tool_use() | Tool or function call |
StepTags.routing() | Agent routing or classification decision |
StepTags.user_interaction() | Human-in-the-loop interaction |
Enums
| Enum | Values |
|---|---|
RiskLevel | LOW, MEDIUM, HIGH, CRITICAL |
SessionOutcome | APPROVED, DENIED, ESCALATED, COMPLETED, ERROR |
Merkle utilities
The SDK exposes the same Merkle functions used internally for transport verification:
from veriproof_sdk import compute_merkle_root_hex, generate_proof, verify_proof
leaves = [
'{"step": "retrieve", "score": 735}',
'{"step": "evaluate", "passed": True}',
'{"decision": "approve", "confidence": 0.91}',
]
root = compute_merkle_root_hex(leaves) # SHA-256 root
proof = generate_proof(leaves, index=2) # Merkle proof path for leaf[2]
assert verify_proof(proof, leaf=leaves[2], root=root)These utilities are useful for independently verifying the integrity of exported compliance records against the root stored in your Solana CMT.
VeriproofSpanExporter
Low-level span exporter — used if you need to attach VeriProof to an existing OTel provider without calling configure_veriproof.
from veriproof_sdk import VeriproofSpanExporter, VeriproofClientOptions
from opentelemetry.sdk.trace.export import BatchSpanProcessor
exporter = VeriproofSpanExporter(
VeriproofClientOptions(api_key="vp_cust_...", application_id="my-app")
)
existing_provider.add_span_processor(BatchSpanProcessor(exporter))Transport reliability
The exporter uses a per-endpoint circuit breaker. If the ingest API returns 3 consecutive errors or connection failures:
- The circuit opens — spans are buffered locally instead of exported.
- After 30 seconds (configurable), the circuit enters half-open and retries one request.
- On success, the circuit closes and buffered spans are flushed.
The in-memory buffer holds up to 500 payloads (configurable via buffer_capacity). When the buffer is full, oldest payloads are dropped. For critical workloads requiring zero payload loss, use the Enterprise Federated deployment with a local relay.
FAQ
Can I use the SDK alongside my existing OTel setup?
Yes. Use existing_provider to attach VeriProof as an additional exporter. Your existing traces continue flowing to their current backends.
Does the SDK work in async and sync code?
Yes. VeriproofSession supports both async with session: and with session: usage patterns.
How do I test that spans are being exported?
Set the environment variable VERIPROOF_DEBUG=true to enable verbose logging in the exporter. Each batch sent to the ingest API will be logged with its Merkle root and span count.
Next steps
- SDK Annotations (Python) —
@trace_operationdecorator reference - Framework Adapters — LangGraph — auto-instrumentation for LangGraph
- Examples — Python — runnable code for all supported frameworks