# LangChain and LangGraph

The `langchain-veqen` package exposes Veqen's maintained callback handler. Attach it to a model or graph invocation to record usage without prompt or response text.

```bash
pip install langchain-veqen langchain-openai
```

```python
import veqen
from langchain_openai import ChatOpenAI
from langchain_veqen import VeqenCallbackHandler

veqen.init(ledger_file="ai-costs.jsonl")
model = ChatOpenAI(model="gpt-4o-mini", stream_usage=True)
answer = model.invoke(
    "Explain the difference between input and output tokens.",
    config={"callbacks": [VeqenCallbackHandler(customer="demo", feature="assistant")]},
)
veqen.flush()
```

Set `OPENAI_API_KEY` for this example. Local recording needs no Veqen account. To also send usage to your organization, set `VEQEN_API_KEY` to an ingest-only key before starting the process. Create it under Settings → API keys, following the [quickstart](/docs/quickstart), and keep it on the server.

## LangGraph

Pass the handler through the callback configuration on your graph invocation so it reaches nested model calls:

```python
result = graph.invoke(
    inputs,
    config={"callbacks": [VeqenCallbackHandler(customer="demo", project="research-agent")]},
)
```

Here `graph` is your compiled graph and `inputs` is its normal input. Use one recording path per model call: adding this handler and wrapping the same provider client can record the call twice.

## Usage and budget behavior

The handler reads standard `AIMessage.usage_metadata`, model identifiers and provider metadata. Enable streaming usage in your model integration when streaming. Calls without usage metadata or a model identifier are skipped rather than assigned guessed counts. Cache reads and cache writes are separated from uncached input tokens. This callback handles token-based chat usage; use the [Python SDK](/docs/python) for provider-specific media billing fields.

Cost uses the versioned [price book](/docs/price-book). It remains an estimate until [reconciled with the provider bill](/docs/reconciliation). Local budgets and cached cloud budget decisions are checked before model execution; [budget documentation](/docs/budgets) explains refresh intervals and concurrency limits.

The same class remains available as `veqen.integrations.langchain.VeqenCallbackHandler` for existing `veqen[langchain]` installations. [Source and tests](https://github.com/Keyveve/veqen-sdks/tree/main/integrations/langchain) are public.
