Docs / SDKs / Python
// PYTHON SDK
Agentics SDK — Python
Drop-in OpenAI-compatible client. Change one base_url, keep your existing SDK, and every call is routed, budgeted, guarded, and lands a cryptographically verifiable receipt on the ledger.
The receipt is written server-side. The SDK never signs, hashes, or sets
billable. It attaches identity headers; the gateway's Proof Ledger writes the one verifiable parent receipt. Per-user attribution and provable savings start at your call site.
Install
shell
pip install agentics openaiQuickstart — the base_url swap
Use your existing OpenAI SDK unchanged. The only change is the base_url and the create_headers() default headers.
Python
from openai import OpenAI # your existing SDK, unchanged
from agentics import create_headers
client = OpenAI(
base_url="https://agentics.you/api/v1", # ← the only change
api_key="ak_…", # your gateway key
default_headers=create_headers(
user="alice@acme.com", # per-user attribution
metadata={"cost_center": "support"}, # tags into the receipt
),
)
resp = client.chat.completions.create(
model="@anthropic/claude-opus-4-8", # @provider/model routing
messages=[{"role": "user", "content": "hi"}],
)
print(resp.headers["x-agentics-receipt"]) # the receipt_hash you can verifyOr: the self-contained gateway client
No openai dependency required. AgenticsGateway is stdlib-only and adds per-call .with_options(...).
Python
from agentics import AgenticsGateway
gw = AgenticsGateway(
base_url="https://agentics.you/api/v1",
api_key="ak_…",
)
# .with_options returns a shallow copy with merged headers — never mutates `gw`.
resp = gw.with_options(
user="alice@acme.com",
trace_id="11111111-1111-4111-8111-111111111111", # correlates the whole fan-out
).chat.completions.create(
model="@anthropic/claude-opus-4-8",
messages=[{"role": "user", "content": "hi"}],
)
# Streaming passes through unchanged (the gateway tees + meters server-side):
for chunk in gw.chat.completions.create(
model="@anthropic/claude-haiku-4", messages=[...], stream=True):
print(chunk)Trace & metadata headers
create_headers() produces exactly this frozen header set. These become the parent receipt's identity fields — client context flows into the verifiable ledger.
| Header | Maps to | Notes |
|---|---|---|
| x-agentics-trace-id | metadata.trace_id | auto-generated UUID; propagated to all child receipts |
| x-agentics-span-id | metadata.span_id | optional |
| x-agentics-user | principal_user_id | per-user attribution + budget scoping |
| x-agentics-meta | merged metadata | JSON, ≤4KB, PII-redacted server-side |
| x-agentics-debug: false | DO-NOT-TRACK | content-free metering receipt; body hashes are sentinels |
Auto-instrumentation
Python
from agentics import AgenticsGateway, LangchainCallbackHandler
gw = AgenticsGateway(instrumentation=True) # wires popular agent frameworks if present
handler = LangchainCallbackHandler(user="alice@acme.com")
chain.invoke(input, config={"callbacks": [handler]})Verify a receipt
Python + CLI
# list the Model Catalog
from agentics import AgenticsGateway
for m in AgenticsGateway().list_models(provider="anthropic"):
print(m["slug"])
# end-to-end verification from the CLI:
# agentics proof verify <receipt_hash>
# agentics log tail --limit 5 # shows your trace_id on the ledger row
Never embed a provider key in client code. Provider keys live in Key Vault, referenced by
secret_ref in your gateway config. The only credential the SDK holds is your Agentics ak_ key (or a short-lived gw_ token). x-target overrides are validated server-side — a tenant cannot point the gateway at an arbitrary internal host.