> 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.

# Groq (tracing)

> Trace Groq Python SDK chat, streaming, and tool calls with Respan.

The [Groq Python SDK](https://github.com/groq/groq-python) is the official client for Groq's inference API. `respan-instrumentation-groq` activates the Groq OpenInference wrapper and normalizes emitted spans to the Respan tracing pipeline.

#### Set up Respan

1. **Sign up** - Create an account at [platform.respan.ai](https://platform.respan.ai)
2. **Create an API key** - Generate one on the [API keys page](https://platform.respan.ai/platform/gateway/api-keys)

#### Use Respan Gateway

See [Groq gateway setup](/docs/gateway/groq) to route Groq model calls through the Respan gateway.

#### Example projects

* [Respan example projects](https://github.com/respanai/respan-example-projects)

## Setup

#### Install packages

```bash
pip install respan-ai respan-instrumentation-groq groq python-dotenv
```

#### Set environment variables

```bash
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
export GROQ_API_KEY="YOUR_GROQ_API_KEY"
```

Optional:

```bash
export RESPAN_BASE_URL="https://api.respan.ai/api"
export GROQ_MODEL="llama-3.1-8b-instant"
```

#### Initialize and run

```python
import os

from dotenv import load_dotenv
from groq import Groq
from respan import Respan, workflow
from respan_instrumentation_groq import GroqInstrumentor

load_dotenv()

respan = Respan(
    api_key=os.environ["RESPAN_API_KEY"],
    base_url=os.getenv("RESPAN_BASE_URL", "https://api.respan.ai/api"),
    instrumentations=[GroqInstrumentor()],
)
client = Groq(api_key=os.environ["GROQ_API_KEY"])


@workflow(name="groq_chat_completion")
def run_chat() -> str:
    response = client.chat.completions.create(
        model=os.getenv("GROQ_MODEL", "llama-3.1-8b-instant"),
        messages=[
            {
                "role": "user",
                "content": "Reply with one concise sentence about tracing.",
            }
        ],
    )
    return response.choices[0].message.content or ""


try:
    print(run_chat())
finally:
    respan.shutdown()
```

#### View your trace

Open the [Traces page](https://platform.respan.ai/platform/traces) and search for the workflow name `groq_chat_completion`.

## Configuration

| Parameter               | Type   | Default | Description                                                                        |
| ----------------------- | ------ | ------- | ---------------------------------------------------------------------------------- |
| `**instrumentor_kwargs` | `dict` | `{}`    | Extra keyword arguments forwarded to the upstream Groq OpenInference instrumentor. |

## Attributes

Attach customer identifiers, thread IDs, workflow names, and metadata to Groq calls with `propagate_attributes`.

```python
from respan import propagate_attributes

with propagate_attributes(
    customer_identifier="user_123",
    thread_identifier="conversation_456",
    trace_group_identifier="groq_support_chat.workflow",
    metadata={"plan": "pro", "workflow_name": "groq_support_chat.workflow"},
):
    response = client.chat.completions.create(
        model="llama-3.1-8b-instant",
        messages=[{"role": "user", "content": "Summarize our support policy."}],
    )
```

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

## Examples

### Streaming

```python
stream = client.chat.completions.create(
    model="llama-3.1-8b-instant",
    messages=[{"role": "user", "content": "Write a short haiku about tracing."}],
    stream=True,
)

for chunk in stream:
    content = chunk.choices[0].delta.content
    if content:
        print(content, end="", flush=True)
```

### Tool calling

```python
response = client.chat.completions.create(
    model="llama-3.1-8b-instant",
    messages=[{"role": "user", "content": "What is the weather in Boston?"}],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "Get the current weather for a city.",
                "parameters": {
                    "type": "object",
                    "properties": {"city": {"type": "string"}},
                    "required": ["city"],
                },
            },
        }
    ],
)
print(response.choices[0].message.tool_calls)
```