Python SDK
Python 3.10+. A run context manager (sync + async), one-line auto-instrumentation for six LLM providers and five agent frameworks, and non-blocking background delivery.
Install
pip install agentping-io
The import name is agentping. Single runtime dependency: httpx.
Quickstart
import agentping
agentping.init() # reads AGENTPING_API_KEY from the environment
with agentping.run("support-triage", customer_id="acme-corp",
goal="Triage the ticket and route it correctly") as r:
r.event("log", {"message": "classifying ticket"})
r.event("llm_call", {
"provider": "anthropic",
"model": "claude-sonnet-4-5",
"input_tokens": 1024,
"output_tokens": 312,
"latency_ms": 1430,
})
r.finish(scores={"confidence": 0.93})
Scores ride on finish(status="success", output=None, scores=None); calling it inside the block is fine, the context manager then skips its own finish. Otherwise the context manager finishes with status="success" on clean exit and status="failed" (capturing repr(exc) into output.error) on exception. r.id is populated before the with block enters. The optional goal tells evaluations what the run was supposed to achieve.
Auto-instrumentation
Each provider has its own one-line patch. Call once at module load; the patch is idempotent and global. LLM calls inside an active agentping.run(...) emit llm_call events with provider, model, token counts, and latency. Cost is computed server-side.
import agentping
agentping.init()
# Each line is independent; enable only what you use:
agentping.instrument_anthropic() # Claude: Messages API, streaming, tool use
agentping.instrument_openai() # GPT: chat.completions, responses, streaming
agentping.instrument_gemini() # google-genai: generateContent, streaming, embeddings
agentping.instrument_mistral() # mistralai 2.x: chat.complete, chat.stream
agentping.instrument_cohere() # cohere 5.x V2 client: chat, chat_stream, embed
agentping.instrument_bedrock() # boto3 bedrock-runtime: Converse, InvokeModel, streams
agentping.instrument_pydantic_ai() # one llm_call per Agent.run / run_sync
agentping.instrument_crewai() # one aggregated llm_call per Crew.kickoff
agentping.instrument_openai_agents() # hooks attached to every Runner.run
Each provider ships as an extra so the provider SDK is pulled in at a supported version: pip install "agentping-io[anthropic]", [openai], [gemini], [mistral], [cohere], [bedrock], [pydantic-ai], [crewai], [openai-agents], [langchain], [llamaindex]. LangChain and LlamaIndex are callback handlers rather than patches: agentping.AgentPingCallbackHandler() goes in LangChain's callbacks, agentping.AgentPingLlamaIndexHandler() on LlamaIndex's Settings.callback_manager.
Each integration has its own page with the exact fields it records and what it does not cover: Anthropic, OpenAI, Google Gemini, Mistral, Cohere, Amazon Bedrock, OpenAI Agents SDK, LangChain, Pydantic AI, LlamaIndex, CrewAI.
For a provider or framework that is not on the list, report the call yourself with r.event("llm_call", {...}); cost is computed server-side from the same rate card.
If the installed provider SDK is outside the supported range, the patch is skipped and a single warning is logged. Agent Ping's SDK never blocks user code; if a wrapper hits an internal error the request still completes normally and only the telemetry is lost.
Heartbeats
agentping.heartbeat(
"daily-summary",
status="ok",
cost_usd=0.084,
duration_ms=12_300,
metadata={"items": 47},
)
Same table as full runs. Upgrading later requires no data migration.
Context propagation
# Env var, picked up automatically on init:
# AGENTPING_PARENT_RUN=run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6
# Explicit parameter:
with agentping.run("price-fetcher",
parent_run_id="run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6"):
...
Explicit parameter wins over env var.
Flushing
Telemetry flushes automatically on exit (atexit). In a long-running worker that never exits, call agentping.flush() at the end of each unit of work. agentping.status() returns queue depth and the last error for debugging.
Configuration
| Variable | Default |
|---|---|
AGENTPING_API_KEY |
required |
AGENTPING_BASE_URL |
auto-derived from key region (https://<region>.ingest.agentping.io) |
AGENTPING_PARENT_RUN |
optional |
AGENTPING_VERSION |
optional |
init() accepts the same values plus queue_size (default 1000) and a custom transport for testing.
init(version="2026.10.28") labels every run with the build or prompt version that produced it (AGENTPING_VERSION does the same), and run(..., version=...) overrides it per run; the Spend and Verify charts mark where each new version was first seen. init(capture_llm_content=True, llm_content_max_chars=4000) turns on prompt and completion capture on every auto-instrumented llm_call; it is off by default, and each provider page describes what is captured.
Use the team API key (apk_<region>_<32 hex>) for the SDK. Ping tokens (ping_...) are for URLs only.
Source
github.com/agent-ping/agent-ping-python. Public surface in src/agentping/__init__.py.