SDK Reference - Python
Full reference for the Overmind Python SDK — initialize once and every LLM call is automatically traced. Includes provider setup, custom spans, user tagging, and exception capture.
Installation
Section titled “Installation”pip install overmindInstall alongside your LLM provider:
pip install overmind openai # OpenAIpip install overmind anthropic # Anthropicpip install overmind google-genai # Google Geminipip install overmind agno # Agnoinit()
Section titled “init()”Initialize the SDK once at application startup, before any LLM calls. After calling init(), your existing LLM client code is automatically instrumented — no import changes, no proxy.
from overmind import init
init( overmind_api_key="ovr_...", service_name="my-service", environment="production", providers=["openai"],)Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
overmind_api_key | str | None | None | Your Overmind API key. Falls back to OVERMIND_API_KEY env var. |
service_name | str | None | None | Name of your service, shown in the dashboard. Also reads OVERMIND_SERVICE_NAME env var. Defaults to "unknown-service". |
environment | str | None | None | Deployment environment ("production", "staging", etc.). Also reads OVERMIND_ENVIRONMENT env var. Defaults to "development". |
providers | list[str] | None | None | Which LLM providers to instrument. Supported: "openai", "anthropic", "google", "agno". None or empty list = auto-detect all installed providers. |
overmind_base_url | str | None | None | Override the Overmind API endpoint. Falls back to OVERMIND_API_URL env var, then https://api.overmindlab.ai. |
Environment Variables
Section titled “Environment Variables”| Variable | Description |
|---|---|
OVERMIND_API_KEY | Your Overmind API key |
OVERMIND_SERVICE_NAME | Service name (overridden by service_name param) |
OVERMIND_ENVIRONMENT | Environment name (overridden by environment param) |
OVERMIND_API_URL | Custom API endpoint URL |
Provider Examples
Section titled “Provider Examples”OpenAI
from overmind import initfrom openai import OpenAI
init(service_name="my-service", providers=["openai"])
client = OpenAI()response = client.chat.completions.create( model="gpt-5-mini", messages=[{"role": "user", "content": "What is quantum computing?"}],)print(response.choices[0].message.content)Anthropic
from overmind import initimport anthropic
init(service_name="my-service", providers=["anthropic"])
client = anthropic.Anthropic()message = client.messages.create( model="claude-opus-4-5", max_tokens=1024, messages=[{"role": "user", "content": "What is quantum computing?"}],)print(message.content[0].text)Google Gemini
from overmind import initfrom google import genai
init(service_name="my-service", providers=["google"])
client = genai.Client()response = client.models.generate_content( model="gemini-2.0-flash", contents="What is quantum computing?",)print(response.text)Agno
from overmind import initfrom agno.agent import Agentfrom agno.models.openai import OpenAIChat
init(service_name="my-service", providers=["agno"])
agent = Agent(model=OpenAIChat(id="gpt-5"), markdown=True)agent.print_response("Write a haiku about the ocean.")Auto-detect all installed providers
from overmind import init
init(service_name="my-service") # auto-instruments every supported package that is installedget_tracer()
Section titled “get_tracer()”Get the OpenTelemetry Tracer instance for creating custom spans around arbitrary code blocks.
from overmind import init, get_tracer
init(service_name="my-service")
tracer = get_tracer()
with tracer.start_as_current_span("process-document") as span: span.set_attribute("document.id", doc_id) result = process(doc)Raises: RuntimeError if init() has not been called.
Returns: An opentelemetry.trace.Tracer instance.
Custom span example
Section titled “Custom span example”from overmind import init, get_tracerfrom openai import OpenAI
init(service_name="pipeline")
client = OpenAI()tracer = get_tracer()
def summarise_document(doc_id: str, text: str) -> str: with tracer.start_as_current_span("summarise") as span: span.set_attribute("doc.id", doc_id) span.set_attribute("doc.length", len(text))
response = client.chat.completions.create( model="gpt-5-mini", messages=[ {"role": "system", "content": "Summarise the following document concisely."}, {"role": "user", "content": text}, ], ) return response.choices[0].message.contentUsing PromptString for better Agent detection
Section titled “Using PromptString for better Agent detection”When you pass prompts as plain strings, Overmind can still infer Agents from traces, but it has to guess which parts of the text are the template vs the dynamic inputs. The PromptString helper lets you declare this structure explicitly so we can reliably match calls to the right Agent.
from opentelemetry.overmind.prompt import PromptStringfrom openai import OpenAIimport overmindimport uuid
overmind.init(service_name="support-bot", providers=["openai"])
system_prompt = PromptString( id="support_greeter_v1", template="You are a helpful support agent. Greet the user by name. Your name is {agent_name}.", kwargs={"agent_name": "Astra"},)
client = OpenAI()response = client.chat.completions.create( model="gpt-5-mini", messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": "How do I reset my password?"}, ],)Why PromptString helps Overmind
Section titled “Why PromptString helps Overmind”- Stable Agent IDs: The
idfield (for examplesupport_greeter_v1) becomes a strong signal for Overmind’s agent discovery, making it easier to keep all versions of a particular agent grouped together. - Explicit template vs. variables: By separating
templateandkwargs, Overmind can precisely identify the prompt template and treat only the placeholders as dynamic inputs. This leads to cleaner prompt extraction and more accurate optimization. - Better backtesting and suggestions: Because prompts are well-structured, Overmind can generate higher‑quality prompt/model experiments for the right Agent, and you get clearer comparisons (e.g., “support_greeter_v1 on gpt‑4o vs gpt‑4o‑mini”).
- Cross‑provider consistency: Re‑using the same
PromptString.idfor logically identical prompts across OpenAI/Anthropic/Gemini makes it easier for Overmind to understand that they all belong to the same Agent, even when the raw strings differ slightly. - One
PromptStringper call: For each LLM call, you can attach at most onePromptString(either for the system prompt or the user prompt). If the SDK detects more than onePromptStringin a single call, it will raise an error so that agent attribution stays unambiguous.
You can gradually adopt PromptString only for your most important agents first (e.g., customer‑facing flows) and let Overmind infer the rest from free‑form prompts.
set_user()
Section titled “set_user()”Associate the current trace with a user. Call this once per request — typically in middleware — so all LLM calls made during that request are tagged with the user’s identity.
from overmind import set_user
set_user(user_id="user-123", email="alice@example.com", username="alice")Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | str | Yes | Unique user identifier |
email | str | None | No | User’s email address |
username | str | None | No | User’s display name |
FastAPI middleware example
Section titled “FastAPI middleware example”from fastapi import FastAPI, Requestfrom overmind import set_user
app = FastAPI()
@app.middleware("http")async def add_user_context(request: Request, call_next): user = getattr(request.state, "user", None) if user: set_user(user_id=user.id, email=user.email) return await call_next(request)set_tag()
Section titled “set_tag()”Add a custom key-value attribute to the current span. Use this to attach any metadata you want to appear alongside traces in the dashboard.
from overmind import set_tag
set_tag("feature.flag", "new-checkout-flow")set_tag("tenant.id", tenant_id)set_tag("workflow", "order-processing")Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
key | str | Attribute name |
value | str | Attribute value |
capture_exception()
Section titled “capture_exception()”Record an exception on the current span and mark its status as ERROR. Use this in except blocks where you want the trace to reflect the failure.
from overmind import capture_exception
try: result = client.chat.completions.create(...)except Exception as e: capture_exception(e) raiseParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
exception | Exception | The exception to record |
Full Example
Section titled “Full Example”import osfrom overmind import init, get_tracer, set_user, set_tag, capture_exceptionfrom openai import OpenAI
os.environ["OVERMIND_API_KEY"] = "ovr_your_key_here"
init( service_name="customer-support", environment="production", providers=["openai"],)
client = OpenAI()
def handle_support_query(user_id: str, question: str) -> str: set_user(user_id=user_id) set_tag("workflow", "support")
tracer = get_tracer() with tracer.start_as_current_span("handle-query"): try: response = client.chat.completions.create( model="gpt-5-mini", messages=[ {"role": "system", "content": "You are a helpful customer support agent."}, {"role": "user", "content": question}, ], ) return response.choices[0].message.content except Exception as e: capture_exception(e) raise
answer = handle_support_query("user-123", "How do I reset my password?")print(answer)Every call produces a trace in the Overmind dashboard. After 30+ traces, the optimization engine analyses your prompts and suggests improvements.
- Call
init()once: Place it at the top of your entry point (main.py,app.py, etc.) before any LLM calls or framework setup. - Use
service_namemeaningfully: If your app has different agents (e.g., support bot, summariser, code assistant), give each a distinctservice_name. This helps Overmind extract cleaner templates and produce more targeted recommendations. - Tag traces with context: Use
set_user()andset_tag()to add metadata that helps you filter and debug traces in the dashboard. - Let it run: The more traces Overmind collects, the better its recommendations. Run your app normally and check the dashboard after a day or two for initial suggestions.