> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://respan.ai/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://respan.ai/docs/_mcp/server.

# Watsonx (tracing)

> Trace IBM watsonx.ai SDK calls with Respan.

[IBM watsonx.ai](https://cloud.ibm.com/apidocs/watsonx-ai) is IBM's enterprise AI platform for foundation models and embeddings. Respan traces the official `ibm-watsonx-ai` Python SDK so direct Watsonx calls show up with prompts, completions, tool calls, embeddings, token usage, latency, workflow names, and custom metadata.

Use this page when your application calls Watsonx directly with IBM credentials.

#### Set up Respan

Create an account at [platform.respan.ai](https://platform.respan.ai) and grab an [API key](https://platform.respan.ai/platform/gateway/api-keys).

Run `npx @respan/cli setup` to set up with your coding agent.

#### Use Respan Gateway

See [Watsonx gateway setup](/docs/gateway/watsonx) to route Watsonx calls through the Respan gateway.

#### Example projects

* [Python examples](https://github.com/respanai/respan-example-projects/tree/main/python/tracing/watsonx)

## Setup

#### Install packages

```bash
pip install respan-ai respan-instrumentation-watsonx ibm-watsonx-ai
```

#### Set environment variables

```bash
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
export WATSONX_API_KEY="YOUR_WATSONX_API_KEY"
export WATSONX_PROJECT_ID="YOUR_WATSONX_PROJECT_ID"
export WATSONX_URL="https://us-south.ml.cloud.ibm.com"
```

`RESPAN_API_KEY` exports traces to Respan. `WATSONX_API_KEY`, `WATSONX_PROJECT_ID`, and `WATSONX_URL` are used by the IBM Watsonx SDK.

#### Initialize and run

```python
import os

from ibm_watsonx_ai import Credentials
from ibm_watsonx_ai.foundation_models import ModelInference
from respan import Respan
from respan_instrumentation_watsonx import WatsonxInstrumentor

respan = Respan(instrumentations=[WatsonxInstrumentor()])

credentials = Credentials(
    api_key=os.environ["WATSONX_API_KEY"],
    url=os.getenv("WATSONX_URL", "https://us-south.ml.cloud.ibm.com"),
)

model = ModelInference(
    model_id=os.getenv("WATSONX_MODEL_ID", "ibm/granite-3-8b-instruct"),
    credentials=credentials,
    project_id=os.environ["WATSONX_PROJECT_ID"],
    validate=False,
)

response = model.generate(
    prompt="Say hello in three languages.",
    params={"max_new_tokens": 60},
)
print(response["results"][0]["generated_text"])

```

#### View your trace

Open the [Traces page](https://platform.respan.ai/platform/traces) to see the Watsonx SDK spans with model names, prompt and completion content, token usage, latency, and metadata.

## Supported calls

`WatsonxInstrumentor()` traces these official `ibm-watsonx-ai` SDK methods:

| Class            | Methods                                                                                                                              |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `ModelInference` | `generate`, `generate_text`, `generate_text_stream`, `chat`, `chat_stream`, `agenerate`, `agenerate_stream`, `achat`, `achat_stream` |
| `Embeddings`     | `generate`, `embed_query`, `embed_documents`, `agenerate`, `aembed_query`, `aembed_documents`                                        |

Chat spans include tool definitions from `llm.request.functions` and tool calls from the assistant completion. Embedding spans include inputs and usage metadata but do not export embedding vectors.

## Configuration

| Parameter             | Type           | Default | Description                                                               |
| --------------------- | -------------- | ------- | ------------------------------------------------------------------------- |
| `api_key`             | `str \| None`  | `None`  | Falls back to `RESPAN_API_KEY` env var.                                   |
| `base_url`            | `str \| None`  | `None`  | Falls back to `RESPAN_BASE_URL` env var.                                  |
| `instrumentations`    | `list`         | `[]`    | Plugin instrumentations to activate, for example `WatsonxInstrumentor()`. |
| `customer_identifier` | `str \| None`  | `None`  | Default customer identifier for all spans.                                |
| `metadata`            | `dict \| None` | `None`  | Default metadata attached to all spans.                                   |
| `environment`         | `str \| None`  | `None`  | Environment tag, for example `"production"`.                              |

## Attributes

### In Respan()

Set defaults at initialization. These apply to all spans.

```python
from respan import Respan
from respan_instrumentation_watsonx import WatsonxInstrumentor

respan = Respan(
    instrumentations=[WatsonxInstrumentor()],
    customer_identifier="user_123",
    metadata={"service": "watsonx-api", "version": "1.0.0"},
    environment="production",
)
```

### With propagate_attributes

Override attributes for a single request or workflow.

```python
from respan import Respan, propagate_attributes
from respan_instrumentation_watsonx import WatsonxInstrumentor

respan = Respan(instrumentations=[WatsonxInstrumentor()])

def handle_request(user_id: str, prompt: str):
    with propagate_attributes(
        customer_identifier=user_id,
        thread_identifier="conv_abc_123",
        metadata={"plan": "pro"},
    ):
        response = model.generate(prompt=prompt, params={"max_new_tokens": 60})
        print(response["results"][0]["generated_text"])
```

| Attribute             | Type   | Description                                           |
| --------------------- | ------ | ----------------------------------------------------- |
| `customer_identifier` | `str`  | Identifies the end user in Respan analytics.          |
| `thread_identifier`   | `str`  | Groups related messages into a conversation.          |
| `metadata`            | `dict` | Custom key-value pairs. Merged with default metadata. |

## Decorators (optional)

Decorators are not required. Watsonx SDK calls are auto-traced. Use `@workflow` and `@task` when you want to group related Watsonx calls into a named trace.

```python
from respan import Respan, workflow
from respan_instrumentation_watsonx import WatsonxInstrumentor

respan = Respan(instrumentations=[WatsonxInstrumentor()])

@workflow(name="watsonx_answer")
def answer(question: str):
    response = model.chat(
        messages=[{"role": "user", "content": question}],
        params={"max_new_tokens": 80},
    )
    return response["choices"][0]["message"]["content"]

print(answer("What does tracing capture?"))
```