Available for: Python and TypeScript.
wrapOpenRouter() (TypeScript) to trace every call, regardless of which underlying model is used — or patch the openai module with patch_openrouter() (Python), since OpenRouter uses an OpenAI-compatible API.
Installation
openai package as the client in both languages.
Setup
In Python,
patch_openrouter() is an alias for patch_openai() — it monkey-patches the openai module’s chat completions method globally rather than wrapping a single client instance. This means: (1) any openai.OpenAI() client in your process is traced after calling it, whether it points at OpenRouter’s base_url or not; (2) traced events are tagged provider: "openai", not provider: "openrouter"; and (3) cost is calculated from token counts and generic pricing, not from OpenRouter’s own reported cost. The TypeScript wrapOpenRouter() wraps only the client instance you pass it, tags events provider: "openrouter", and prefers OpenRouter’s actual reported cost (see below). There is currently no separate Python codepath that gives OpenRouter-specific cost or provider tagging — patch_openrouter() and patch_openai() are the same function.Example
What gets captured
Cost reporting accuracy in TypeScript depends on whether OpenRouter returns cost data in the response. For most popular models it does. For custom or fine-tuned routes, token-based calculation is used as a fallback.
Send traces without the SDK (Broadcast)
OpenRouter can also send traces on its own, without any Zespan SDK in your app, with its Broadcast feature. Use this instead of the wrapper for a given call, not as well (see below).1
Add an OpenTelemetry Collector destination
In OpenRouter’s Broadcast settings add a destination of type OpenTelemetry Collector and set the endpoint to
https://api.zespan.com/v1/traces. OpenRouter sends JSON.2
Add the project key as a header
In the destination’s custom headers (a JSON object) add
{"x-api-key": "zsp_..."}.3
Test the connection
Press Test connection; OpenRouter saves the destination only if the test passes. OpenRouter documents the test (for its Webhook destination) as an empty export marked
X-Test-Connection: true that passes on a 2xx or 400 answer; Zespan answers 200. Then send one real request and open Settings → Instrumentation → Gateway and OTLP data. A test alone shows as only a test connection has arrived. See Instrumentation.Attribute names come from OpenRouter’s published documentation and can change between versions. Use the Gateway and OTLP data card to see what actually arrives. Zespan recognises OpenRouter by the service name
openrouter; if the card lists the data as OpenTelemetry, it is stored and read the same way but not marked as OpenRouter’s.Next steps
- OTel integration, the endpoint, limits and attributes Zespan reads
- Instrumentation, check what arrived
- LiteLLM Proxy, Portkey, other gateways

