Framework integrations

Track costs from the Vercel AI SDK, LangChain, LiteLLM and the OpenAI Agents SDK without wrapping each client.

Vercel AI SDK

Middleware for AI SDK 5 and 6, on every provider the AI SDK supports. Streaming and non-streaming calls are both priced, cached input included.

import { openai } from "@ai-sdk/openai";
import { generateText, wrapLanguageModel } from "ai";
import { withTags } from "@veqen/sdk";
import { veqen } from "@veqen/sdk/ai-sdk";

const model = wrapLanguageModel({ model: openai("gpt-5-mini"), middleware: veqen({ feature: "chat" }) });

await withTags({ customer: org.id }, () => generateText({ model, prompt }));

Already exporting AI SDK telemetry? You can send those spans instead: see OpenTelemetry.

LangChain

from veqen.integrations.langchain import VeqenCallbackHandler

handler = VeqenCallbackHandler(feature="rag")
chain.invoke({"question": q}, config={"callbacks": [handler]})
import { VeqenCallbackHandler } from "@veqen/sdk/langchain";

await chain.invoke({ question }, { callbacks: [new VeqenCallbackHandler({ feature: "rag" })] });

The handler reads LangChain's standard usage_metadata, so it works with every chat model integration that reports usage. Install veqen[langchain] in Python; in JavaScript, @langchain/core is a peer dependency.

LiteLLM

For the proxy's CustomLogger class and hosted callback endpoint, see Track LiteLLM costs.

import litellm
from veqen.integrations.litellm import callback

litellm.success_callback = [callback]

litellm.completion(model="anthropic/claude-sonnet-4-5", messages=messages,
                   metadata={"veqen": {"customer": "acme", "feature": "chat"}})

The same callback works in the LiteLLM proxy as a custom callback. Tags come from metadata.veqen or from an enclosing veqen.tags(...) block. Embedding, image and audio calls through LiteLLM are priced too, and LiteLLM's own response_cost is kept for calls that report no usage.

OpenAI Agents SDK

from agents import add_trace_processor
from veqen.integrations.openai_agents import VeqenTracingProcessor

add_trace_processor(VeqenTracingProcessor(feature="support-agent"))

Every model response inside an agent run is priced, including tool-calling loops and handoffs.

Gateways and anything else

OpenAI-compatible APIs (Together, Fireworks, Groq, DeepInfra, Azure AI Foundry, a self-hosted vLLM or TGI) work through the wrapped OpenAI client: the provider is read from the client's base URL, and the model name it reports is looked up across every provider in the price book. Name your own servers with wrap(client, provider="self-hosted") and give them a custom price. Through OpenRouter, model ids such as anthropic/claude-sonnet-4.5 are priced at the underlying provider's list price; OpenRouter's own fees aren't included.

For anything else (fal and Replicate jobs, Runway, ElevenLabs, Deepgram, a batch pipeline, another language), call record() with the tokens or units the call used; see the Python and JavaScript SDKs.