PromptRail

RUNTIME SDK · PYTHON 3.11+

Observe once.
Budget every call.

Connect your application's live execution context and historical traces to PromptRail. The SDK adds run, user, trace, and span identity while the control plane assigns cost and latency budgets.

01

Quickstart

One process-level initialization. One wrapped client.

Install

pip install "promptrail[runtime]"

Initialize

import os
from promptrail import PromptRail

PromptRail.init(
    api_key=os.environ["PROMPTRAIL_API_KEY"],
    application="support-agent",
    environment="production",
)

Wrap your client

from openai import OpenAI
from promptrail import run, wrap_openai

client = wrap_openai(OpenAI(
    base_url="https://api.promptrail.ai/v1",
    api_key=os.environ["PROMPTRAIL_API_KEY"],
))

with run(user_id="customer_123"):
    response = client.responses.create(
        model="gpt-4o-mini",
        input="Summarize the open support ticket.",
    )
Shutdown cleanly.Call PromptRail.shutdown() during orderly process shutdown so queued telemetry gets its full flush deadline.
02

Configuration

Metadata-only by default, bounded at every layer.

OptionDefaultPurpose
applicationNoneStable application or agent name
environmentNoneSeparate production and development behavior
user_idNoneStable string or resolver callback
privacy_modemetadata_onlyExclude content from telemetry
queue_size2048Maximum queued events
batch_size50Maximum events per export batch
enable_opentelemetryTrueAttach the PromptRail span processor
03

OpenAI integration

Explicit instrumentation, no monkey-patching.

The wrapper supports synchronous and asynchronous chat completions, completions, responses, streaming responses, and embeddings. It checks base_url on every call and only adds private PromptRail headers to the configured gateway origin.

04

OpenTelemetry

Add one observer without replacing your exporters.

from opentelemetry import trace
from promptrail import PromptRail

PromptRail.init(api_key=api_key, application="research-agent")
tracer = trace.get_tracer("my.application")

with tracer.start_as_current_span(
    "search-repository",
    attributes={"promptrail.span.type": "tool", "tool.name": "search_repository"},
):
    search_repository()
05

Historical traces

Teach PromptRail how your application normally executes.

from pathlib import Path
from promptrail import import_historical_traces

history = import_historical_traces(
    Path("traces.jsonl").read_bytes(),
    metadata_only=True,
)
print(history.summary())

Accepted formats include PromptRail event batches, JSONL, generic span exports, and OpenTelemetry resourceSpans. Imports are limited to 50 MB.

Open the trace connection interface →
06

Privacy

Operational metadata in. Prompts and responses out.

Excluded by default

Prompts, completions, messages, documents, source code, request bodies, responses, and tool input/output.

Retained metadata

IDs, model and tool names, token counts, durations, hashes, sizes, MIME types, and statuses.

07

Event schema 1.0

One canonical shape for live and historical execution.

{
  "schema_version": "1.0",
  "event_id": "evt_01...",
  "run_id": "run_01...",
  "trace_id": "0123456789abcdef0123456789abcdef",
  "span_id": "0123456789abcdef",
  "type": "llm.end",
  "timestamp_ms": 1720000000000,
  "attributes": {"input_tokens": 420, "duration_ms": 730}
}
08

Troubleshooting

Fast checks for the failure modes that matter.

Wrapped calls contain no PromptRail headers

Initialize before the request, confirm the client base URL matches the configured gateway origin, and use a supported OpenAI resource.

Events are not exported

Confirm the API key, event endpoint, and export_enabled. Call shutdown before process exit and use debug mode for sanitized diagnostics.

Context disappears in a thread

Python context variables do not automatically cross thread-pool submissions. Use submit_with_context.