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

# Portkey (tracing)

> Trace Portkey Python SDK chat and async calls with Respan.

The [Portkey Python SDK](https://github.com/Portkey-AI/portkey-python-sdk) routes requests through Portkey Gateway. `respan-instrumentation-portkey` activates the Portkey 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 [Portkey gateway setup](/docs/gateway/portkey) to replace Portkey Gateway routing with 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-portkey portkey-ai python-dotenv
```

#### Set environment variables

```bash
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
export PORTKEY_API_KEY="YOUR_PORTKEY_API_KEY"
export PORTKEY_PROVIDER="@YOUR_PROVIDER"
```

Use `PORTKEY_CONFIG` instead of `PORTKEY_PROVIDER` if your Portkey account uses a config slug.

Optional:

```bash
export RESPAN_BASE_URL="https://api.respan.ai/api"
export PORTKEY_MODEL="gpt-4o-mini"
```

#### Initialize and run

```python
import os

from dotenv import load_dotenv
from portkey_ai import Portkey
from respan import Respan, workflow
from respan_instrumentation_portkey import PortkeyInstrumentor

load_dotenv()

respan = Respan(
    api_key=os.environ["RESPAN_API_KEY"],
    base_url=os.getenv("RESPAN_BASE_URL", "https://api.respan.ai/api"),
    instrumentations=[PortkeyInstrumentor()],
)
client = Portkey(
    api_key=os.environ["PORTKEY_API_KEY"],
    provider=os.getenv("PORTKEY_PROVIDER"),
    config=os.getenv("PORTKEY_CONFIG"),
)


@workflow(name="portkey_chat_completion")
def run_chat() -> str:
    response = client.chat.completions.create(
        model=os.getenv("PORTKEY_MODEL", "gpt-4o-mini"),
        messages=[{"role": "user", "content": "Say hello from Portkey."}],
    )
    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 `portkey_chat_completion`.

## Configuration

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

## Attributes

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

```python
from respan import propagate_attributes

with propagate_attributes(
    customer_identifier="user_123",
    thread_identifier="conversation_456",
    trace_group_identifier="portkey_support_chat.workflow",
    metadata={"plan": "pro", "workflow_name": "portkey_support_chat.workflow"},
):
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        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

### Async chat

```python
import asyncio
import os

from portkey_ai import AsyncPortkey


async def main() -> None:
    client = AsyncPortkey(
        api_key=os.environ["PORTKEY_API_KEY"],
        provider=os.getenv("PORTKEY_PROVIDER"),
        config=os.getenv("PORTKEY_CONFIG"),
    )
    try:
        response = await client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": "Write a short haiku about traces."}],
        )
        print(response.choices[0].message.content)
    finally:
        await client.close()


asyncio.run(main())
```