Skip to content
Get started

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.

Terminal window
pip install overmind

Install alongside your LLM provider:

Terminal window
pip install overmind openai # OpenAI
pip install overmind anthropic # Anthropic
pip install overmind google-genai # Google Gemini
pip install overmind agno # Agno

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"],
)
ParameterTypeDefaultDescription
overmind_api_keystr | NoneNoneYour Overmind API key. Falls back to OVERMIND_API_KEY env var.
service_namestr | NoneNoneName of your service, shown in the dashboard. Also reads OVERMIND_SERVICE_NAME env var. Defaults to "unknown-service".
environmentstr | NoneNoneDeployment environment ("production", "staging", etc.). Also reads OVERMIND_ENVIRONMENT env var. Defaults to "development".
providerslist[str] | NoneNoneWhich LLM providers to instrument. Supported: "openai", "anthropic", "google", "agno". None or empty list = auto-detect all installed providers.
overmind_base_urlstr | NoneNoneOverride the Overmind API endpoint. Falls back to OVERMIND_API_URL env var, then https://api.overmindlab.ai.
VariableDescription
OVERMIND_API_KEYYour Overmind API key
OVERMIND_SERVICE_NAMEService name (overridden by service_name param)
OVERMIND_ENVIRONMENTEnvironment name (overridden by environment param)
OVERMIND_API_URLCustom API endpoint URL

OpenAI

from overmind import init
from 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 init
import 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 init
from 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 init
from agno.agent import Agent
from 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 installed

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.

from overmind import init, get_tracer
from 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.content

Using 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 PromptString
from openai import OpenAI
import overmind
import 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?"},
],
)
  • Stable Agent IDs: The id field (for example support_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 template and kwargs, 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.id for 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 PromptString per call: For each LLM call, you can attach at most one PromptString (either for the system prompt or the user prompt). If the SDK detects more than one PromptString in 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.


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")
ParameterTypeRequiredDescription
user_idstrYesUnique user identifier
emailstr | NoneNoUser’s email address
usernamestr | NoneNoUser’s display name
from fastapi import FastAPI, Request
from 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)

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")
ParameterTypeDescription
keystrAttribute name
valuestrAttribute value

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)
raise
ParameterTypeDescription
exceptionExceptionThe exception to record

import os
from overmind import init, get_tracer, set_user, set_tag, capture_exception
from 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_name meaningfully: If your app has different agents (e.g., support bot, summariser, code assistant), give each a distinct service_name. This helps Overmind extract cleaner templates and produce more targeted recommendations.
  • Tag traces with context: Use set_user() and set_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.