Skip to main content

MetricAI Python SDK

AI billing and metering proxy for India — route LLM calls, track costs, attribute spend, and manage budgets in INR/UPI.

PyPI Version Python Versions License: MIT


Modes

MetricAI SDK supports two modes of operation:

Mode Description
Cloud Mode Route traffic through MetricAI proxy with SaaS dashboard
Local Mode Zero-egress tracking with local SQLite and dashboard

Local Mode is ideal for:

  • Enterprise deployments
  • Air-gapped environments
  • Compliance requirements
  • Cost-sensitive projects

Get started with Local Mode: Quick Start Guide


Features

Capability Description
Local Mode (NEW) Zero-egress tracking with SQLite — no data leaves your environment
Multi-Provider Proxy Route OpenAI, Anthropic, Gemini, Grok, Groq, Perplexity, and more through a single endpoint
Native SDK Compatibility Use official provider SDKs with zero code changes via instrument()
Per-Agent & Per-User Attribution Group costs by agent_id and user_id in the dashboard
Budget Caps Hard INR caps per agent or conversation to prevent runaway spend
Outcome Billing Charge on success/failure outcomes, not just token usage
Streaming Telemetry Track token counts and tool usage in real-time for streaming responses
Agentic Workflows Built-in MetricAIAgent and MetricAIPipeline with tool calling and governance
Framework Integrations LangChain, LangGraph, CrewAI, LlamaIndex, AutoGen, FastAPI, Django
Voice AI Tracking Deepgram, ElevenLabs, Sarvam with voice-specific metrics
LiveKit Integration Track LiveKit voice agents with billing and attribution
Invoice payments Generate hosted pay links for end-customer invoices (create_invoice_payment_link)
Y subscriptions Recurring plans for end customers (create_end_user_subscription, get_end_user_wallet)
Programmatic projects Create a project + key (create_project); add a teammate without confirmation (add_project_member)
Fail-Open Requests forward directly to providers if the proxy is unreachable

Installation

pip install metricai

With Optional Providers

# Just OpenAI
pip install "metricai[openai]"

# Just Anthropic
pip install "metricai[anthropic]"

# All providers at once
pip install "metricai[all]"

Available extras: openai, anthropic, gemini, groq, grok, perplexity, bedrock, tavily, langchain, langgraph, crewai, llamaindex, fastapi, django, deepgram, elevenlabs, sarvam


Quickstart

1. Set your API key

export METRICAI_API_KEY="your_metricai_api_key"

To create a project (and a project API key) without the dashboard:

from metricai import MetricAI

client = MetricAI(api_key="your_personal_metricai_api_key")
result = client.create_project("Acme Agents", api_key_name="CI key")
print(result["project"]["project_id"])
print(result["api_key"])  # shown once — store it

# Add an existing MetricAI user (no confirmation). role: admin | member | observer
client.add_project_member("Acme Agents", "teammate@example.com", role="member")
client.add_project_member("Acme Agents", "lead@example.com", role="admin")
client.add_project_member("Acme Agents", "finance@example.com", role="observer")

For BYOK mode (bring your own provider keys):

export METRICAI_API_KEY="your_metricai_api_key"
export OPENAI_API_KEY="sk-proj-..."        # Optional — for OpenAI routes
export ANTHROPIC_API_KEY="sk-ant-..."      # Optional — for Anthropic routes
export GEMINI_API_KEY="AI..."              # Optional — for Gemini routes

2. Use native SDKs via proxy

from metricai import MetricAI

client = MetricAI(api_key="your_metricai_api_key")

# OpenAI via proxy
openai_client = client.openai_sdk(agent_id="support-agent", user_id="user_42")
response = openai_client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather in Mumbai?"}]
)
print(response.choices[0].message.content)

3. Track usage and costs

from metricai import MetricAI, MetricAISession, timed_call

client = MetricAI(api_key="your_metricai_api_key")

# Session-based tracking with budget cap
with MetricAISession(client, agent_id="booking-agent", user_id="user_123", max_budget_inr=50.0) as session:
    response = client.openai_sdk().chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "Book a flight to Delhi"}]
    )
    session.track(provider="openai", model="gpt-4o-mini", input_tokens=1500, output_tokens=300)

4. Outcome billing

# Simulate first to estimate cost
client.track(
    provider="openai",
    model="gpt-4o-mini",
    outcome={"success": True, "outcome_type": "booking_confirmed", "charge_on_success_inr": 2.5},
    simulate=True,
)

# Live outcome billing
client.track(
    provider="openai",
    model="gpt-4o-mini",
    outcome={"success": True, "charge_on_success_inr": 2.5},
    latency_ms=850,
)

5. Standalone agent with tools

from metricai import MetricAI
from metricai.workflow import MetricAIAgent

client = MetricAI(api_key="your_metricai_api_key", llm_keys={"gemini": "your_gemini_key"})

agent = MetricAIAgent(
    client,
    agent_id="research-agent",
    user_id="user_456",
    model="gemini-2.0-flash",
    system_prompt="You are a helpful research assistant.",
    budget_cap_inr=25.0,
)

response = agent.run("What are the top 5 AI news stories today?")
print(response.content)

Invoice payments

Collect final_usd from an end customer (Y) with a hosted pay page. Invoice REST calls go to the API host (api.metricai.co.in / staging-api.metricai.co.in), not the LLM proxy. Override with METRICAI_API_URL or MetricAI(api_base_url=...).

Finish dashboard onboarding first: Settings → Billing (Route or BYOR), then Payouts (Route) or Payments (BYOR) until the account is ready to collect.

from metricai import MetricAI

client = MetricAI(api_key="your_metricai_api_key")

invoice = client.get_invoices("cust_123", period_start="01082026", period_end="31082026")
link = client.create_invoice_payment_link(
    "cust_123",
    period_start=invoice["period_start"],
    period_end=invoice["period_end"],
)
# Redirect the customer to link["payment_url"]  →  https://pay.metricai.co.in/i/{token}

status = client.get_invoice_payment_status(
    "cust_123",
    period_start=invoice["period_start"],
    period_end=invoice["period_end"],
)
# status["payment_status"] is "unpaid" | "pending" | "paid"

If you collect on your own Razorpay checkout (BYOR self-collect), call client.mark_invoice_collected(...) after a successful payment so MetricAI can accrue platform fees.

In a team project only the project owner can create a payment link or mark an invoice collected. A member's API key raises MetricAIError with that reason; get_invoice_payment_status stays available to every member.

Runnable example: examples/invoice_payment_link.py. Guides: Route, BYOR hosted, BYOR self-collect.

End-user subscriptions

Sell a recurring plan to Y. Create a Subscription + overage policy in the dashboard (or list_billing_policies()), then:

sub = client.create_end_user_subscription("cust_123")
# Redirect Y to sub["payment"]["payment_url"]
wallet = client.get_end_user_wallet("cust_123")
# wallet["balance_usd"] is included usage remaining

Usage burns the wallet; leftover is invoiced as overage. Owner-only start/cancel in team projects. Requires END_USER_SUBSCRIPTIONS_ENABLED on the API.

Prepaid wallet top-up

Y can also pay X a lump sum in $10 multiples (10, 20, 40, …). The full paid amount credits the customer wallet. After you mint the link, get_invoices() returns the receipt (pass the period_start / period_end from the response).

link = client.create_end_user_wallet_topup("cust_123", 40, project_id="proj-1")
# Redirect Y to link["payment_url"]
invoice = client.get_invoices(
    "cust_123",
    start_date=link["period_start"],
    end_date=link["period_end"],
)

Core Concepts

Client Initialization

from metricai import MetricAI, MetricAIConfig

# Simple initialization
client = MetricAI(api_key="your_metricai_api_key")

# With configuration object
config = MetricAIConfig(
    api_key="your_metricai_api_key",
    mode="byok",                        # "byok" or "managed"
    llm_keys={"openai": "sk-..."},     # Provider keys for BYOK mode
    proxy_base_url="https://proxy.metricai.co.in",
    default_billing_mode="hybrid",      # "usage", "outcome", or "hybrid"
    default_budget_cap_inr=100.0,       # Daily INR cap
    fail_open=True,                     # Forward to provider if proxy unreachable
)

client = MetricAI(config=config)

Headers and Attribution

# Get headers for any SDK call
headers = client.headers(
    agent_id="my-agent",
    user_id="user_123",
    session_id="session_abc",
    billing_mode="hybrid",
    budget_cap_inr=50.0,
)

# Pass headers to any HTTP client
response = openai_client.chat.completions.create(
    model="gpt-4o",
    messages=[...],
    extra_headers=headers,
)

Routing

from metricai import MetricAI, RoutingConfig, RoutingManager

client = MetricAI(api_key="your_metricai_api_key")

# Configure routing policy server-side
router = RoutingManager(client)
router.configure(
    agent_id="routing-agent",
    strategy="cost-optimized",
    config={"max_model": "gpt-4o-mini", "fallback_model": "gpt-3.5-turbo"}
)

# Or via config
client = MetricAI(
    api_key="your_metricai_api_key",
    routing=RoutingConfig(strategy="latency-optimized")
)

Global Instrumentation

Instrument all provider SDK clients globally — no need to change existing code:

from metricai import init, instrument

# Initialize once at app startup
init(api_key="your_metricai_api_key", auto_instrument=True)

# All subsequent OpenAI/Anthropic calls are automatically routed through MetricAI
from openai import OpenAI
client = OpenAI()  # Already patched — routes through MetricAI proxy

Framework Integrations

LangChain

from langchain_openai import ChatOpenAI
from metricai.integrations.langchain import MetricAIChatCallbackHandler

handler = MetricAIChatCallbackHandler(agent_id="lc-agent", user_id="user_1")
llm = ChatOpenAI(callbacks=[handler])
response = llm.invoke("Hello!")

LangGraph

from langgraph.prebuilt import create_react_agent
from metricai.integrations.langgraph import MetricAIGraphTracer

tracer = MetricAIGraphTracer(agent_id="graph-agent", user_id="user_2")
agent = create_react_agent(model, tools, tracer=tracer)

CrewAI

from crewai import Agent
from metricai.integrations.crewai import MetricAICrewAIWrapper

wrapper = MetricAICrewAIWrapper(api_key="your_key")
agent = wrapper.wrap_agent(
    Agent(role="Researcher", goal="Find AI news", backstory="You are a researcher"),
    agent_id="crewai-researcher",
)

FastAPI Middleware

from fastapi import FastAPI
from metricai.integrations.web import MetricAIFastAPIMiddleware

app = FastAPI()
app.add_middleware(
    MetricAIFastAPIMiddleware,
    api_key="your_metricai_api_key",
    default_agent_id="fastapi-agent",
)

Environment Variables

Variable Description Default
METRICAI_API_KEY Your MetricAI API key Required
METRICAI_PROXY_URL Proxy base URL https://proxy.metricai.co.in
METRICAI_API_URL REST API host for invoices, wallet, auth Derived from the proxy host (api.metricai.co.in)
METRICAI_ENVIRONMENT production or sandbox production
OPENAI_API_KEY BYOK key for OpenAI —
ANTHROPIC_API_KEY BYOK key for Anthropic —
GEMINI_API_KEY BYOK key for Gemini —

Supported Providers

Provider Proxy Path Native SDK
OpenAI /v1/proxy/openai ✅ openai
Anthropic /v1/proxy/claude ✅ anthropic
Gemini /v1/proxy/gemini ✅ google-genai
Grok /v1/proxy/grok ✅ xai-sdk
Groq /v1/proxy/groq ✅ groq
Perplexity /v1/proxy/perplexity ✅ perplexityai
AWS Bedrock /v1/proxy/bedrock ✅ boto3
Tavily /v1/proxy/tavily ✅ tavily-python
Deepgram /v1/proxy/deepgram ✅ deepgram-sdk
ElevenLabs /v1/proxy/elevenlabs ✅ elevenlabs
Sarvam /v1/proxy/sarvam ✅ sarvamai

Error Handling

from metricai import (
    MetricAI,
    MetricAIError,
    MetricAIAuthError,
    MetricAIQuotaExhaustedError,
    MetricAIRateLimitError,
    MetricAIProxyError,
)

client = MetricAI(api_key="your_metricai_api_key")

try:
    response = client.openai_sdk().chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": "Hello"}]
    )
except MetricAIAuthError:
    print("Invalid API key")
except MetricAIQuotaExhaustedError:
    print("Budget cap reached — upgrade your plan")
except MetricAIRateLimitError:
    print("Rate limited — retry after a moment")
except MetricAIProxyError as e:
    print(f"Proxy error: {e}")
except MetricAIError as e:
    print(f"Unexpected error: {e}")

API Reference

MetricAI

Main client class for all operations.

MetricAI(
    api_key: str,                          # Required: your MetricAI API key
    base_url: str | None = None,           # Override proxy URL
    timeout: int = 60,                     # Request timeout in seconds
    agent_id: str | None = None,           # Default agent ID
    user_id: str | None = None,            # Default user ID
    billing_mode: str | None = None,       # "usage", "outcome", or "hybrid"
    budget_cap_inr: float | None = None,   # Daily budget cap in INR
    mode: str = "byok",                    # "byok" or "managed"
    llm_keys: dict | None = None,          # Provider API keys
    config: MetricAIConfig | None = None,  # Configuration object
)

Methods:

  • openai_sdk(...) → Returns OpenAI-compatible client routed through proxy
  • anthropic_sdk(...) → Returns Anthropic client routed through proxy
  • gemini_sdk(...) → Returns Gemini client routed through proxy
  • grok_sdk(...) → Returns Grok client routed through proxy
  • headers(...) → Returns headers dict for any SDK call
  • track(...) → Track a billing event
  • track_stream(...) → Track streaming responses
  • session(...) → Context manager for session tracking
  • get_quota_status() → Get current billing usage

MetricAISession

Session context manager for grouped tracking:

with MetricAISession(
    client,
    agent_id="my-agent",
    user_id="my-user",
    max_budget_inr=50.0,
) as session:
    # Your LLM calls here
    session.track(provider="openai", model="gpt-4o", input_tokens=100, output_tokens=50)

MetricAIAgent

Tool-capable agent with built-in governance:

agent = MetricAIAgent(
    client,
    agent_id="my-agent",
    user_id="my-user",
    provider="openai",          # or "anthropic", "gemini", "grok"
    model="gpt-4o",
    system_prompt="You are a helpful assistant.",
    tools=[...],                # Optional: list of tool definitions
    max_iterations=10,
    budget_cap_inr=25.0,
    billing_mode="hybrid",
)

response = agent.run("User's request here")
print(response.content)
print(f"Tokens: {response.input_tokens} + {response.output_tokens}")

Examples

More examples are available in the examples/ directory:


License

MIT License — see LICENSE for details.


Support

Metadata

Release files for metricai 0.8.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for metricai 0.8.6
File Size Uploaded
metricai-0.8.6.tar.gz 16.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for metricai 0.8.6
File Interpreter ABI Platform
metricai-0.8.6-py3-none-any.whl Python 3 none any Details

Total release size: 16.4 MB

Release files / metricai-0.8.6.tar.gz

Download URL metricai-0.8.6.tar.gz
Size 16.1 MB
Tags Source
SHA-256 checksum
How to use checksums
b1f169f98982fb46594aaf13662438833a2da1c0f41d1940f6aee704b40c4aee
BLAKE2b-256 checksum
How to use checksums
dcfc897560d5bdcb738cac28b2fe40677a2837ff3cd878f3905f8e6a512d9e46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / metricai-0.8.6-py3-none-any.whl

Download URL metricai-0.8.6-py3-none-any.whl
Size 268.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b882fc5f955e4326e9e18cd4b147f4ad075429b0c83fd9417bf41ec6606aef1f
BLAKE2b-256 checksum
How to use checksums
30dcb3c79ed19ccf2e03a4f64ca3aff75ad94734145ff3e56caa558250142b7a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

This release

0.8.6 This release

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.0

2 release files

0.7.9

2 release files

0.7.8

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page