> ## Documentation Index
> Fetch the complete documentation index at: /docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Thread management for grouped requests

> Group related AI Gateway requests into conversation threads for observability. Threads label related calls together without storing message history.

**Use Cases**

* Viewing all turns of a multi-turn conversation as a single trace in observability.
* Debugging agent workflows by inspecting the full request sequence end-to-end.
* Organizing support conversations to analyze resolution patterns across sessions.
* Separating concurrent conversations from the same user to avoid mixing traces.

For the full set of ways to attach context to a request, including app name, identity, and custom metadata, see [Request Metadata](/docs/ai-gateway/request-metadata.md).

***

Group related requests into conversation Threads so they appear together in observability. Threads are a labeling mechanism and do not store or inject message history.

Grouping is manual and opt-in: pass the same `thread.id` on every request that belongs to a conversation. API requests without a thread ID appear as individual traces and are never grouped automatically, with one exception: Claude Code and Codex send their own session identifiers, which are detected and grouped automatically.

## Quick Start

Pass `thread` at the top level on `/v3/router/responses`. On `/v3/router/chat/completions`, pass it under the `orq` object as `orq.thread`. To read the threads a workspace has recorded, call [List trace threads](/docs/reference/threads/list-trace-threads.md).

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/responses \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-sol",
    "input": "Start a new conversation about AI",
    "thread": {
      "id": "conversation-abc123",
      "tags": ["ai-discussion", "user-123"]
    }
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.responses.create({
  model: "openai/gpt-5.6-sol",
  input: "Start a new conversation about AI",
  thread: {
    id: `conversation-${crypto.randomUUID()}`,
    tags: ["ai-discussion", "user-123"],
  },
});

console.log(response.output_text);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
import os
import uuid

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

response = client.responses.create(
    model="openai/gpt-5.6-sol",
    input="Start a new conversation about AI",
    extra_body={
        "thread": {
            "id": f"conversation-{uuid.uuid4()}",
            "tags": ["ai-discussion", "user-123"],
        }
    },
)

print(response.output_text)
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.chat.completions.create({
  model: "openai/gpt-5.6-sol",
  messages: [{ role: "user", content: "Start a new conversation about AI" }],
  orq: {
    thread: {
      id: `conversation-${crypto.randomUUID()}`,
      tags: ["ai-discussion", "user-123"],
    },
  },
});
```

## Configuration

| Parameter | Type | Required | Description |
| - | - | - | - |
| `id` | string | Yes | Unique thread identifier for grouping requests |
| `tags` | string\[] | No | Metadata tags for filtering and categorization |

## Best Practices

1. **Consistent Naming**: Use predictable thread ID patterns
2. **Meaningful Tags**: Choose tags that aid in filtering and analysis
3. **Session Management**: Tie thread IDs to user sessions
4. **Unique IDs**: Use UUIDs or composite keys to avoid cross-session overlap

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Good: Descriptive and unique
const threadId = `support-${userId}-${sessionId}-${timestamp}`;

// Good: UUID-based for uniqueness
const threadId = `conversation-${crypto.randomUUID()}`;

// Avoid: Too generic
const threadId = "conversation1";
```

## Use Cases

| Scenario | Thread ID Strategy | Tags Example |
| - | - | - |
| **User Sessions** | `user-{userId}-{sessionId}` | `["user-session", "support"]` |
| **Support Tickets** | `ticket-{ticketId}` | `["support", "priority-high"]` |
| **A/B Testing** | `test-{variant}-{userId}` | `["experiment", "variant-a"]` |
| **Multi-Step Workflows** | `workflow-{processId}` | `["onboarding", "step-2"]` |

## Implementation Examples

### Session-Based Threading

Assign the same `thread.id` to all requests in a session to group them together in observability. Your application manages the messages array for each request.

`thread.id` groups the turns of a single conversation. The `orq.session_id` span attribute groups requests across conversations for broader session tracking; when a request carries both, the thread ID determines the grouping. See [Toqan Router span attributes](/docs/ai-studio/observability/span-attributes.md).

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

// Initialize conversation
const userId = "user-123";
const sessionId = crypto.randomUUID();
const threadId = `user-${userId}-${sessionId}`;

const response = await client.chat.completions.create({
  model: "openai/gpt-5.6-sol",
  messages: [{ role: "user", content: "How do I reset my password?" }],
  orq: {
    thread: {
      id: threadId,
      tags: ["support", "password-reset", `user-${userId}`],
    },
  },
});

// Continue conversation
const followUp = await client.chat.completions.create({
  model: "openai/gpt-5.6-sol",
  messages: [
    { role: "user", content: "How do I reset my password?" },
    { role: "assistant", content: response.choices[0].message.content },
    { role: "user", content: "I didn't receive the reset email" },
  ],
  orq: {
    thread: {
      id: threadId, // Same thread ID
      tags: ["support", "email-issue", `user-${userId}`],
    },
  },
});
```

### Multi-Language Support

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/responses \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-sol",
    "input": "Explain machine learning basics",
    "thread": {
      "id": "tech-discussion-001",
      "tags": ["education", "ml-basics", "beginner"]
    }
  }'
```

```bash cURL (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/chat/completions \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-sol",
    "messages": [{"role": "user", "content": "Explain machine learning basics"}],
    "orq": {
      "thread": {
        "id": "tech-discussion-001",
        "tags": ["education", "ml-basics", "beginner"]
      }
    }
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const threadId = `conversation-${crypto.randomUUID()}`;

const response = await client.responses.create({
  model: "openai/gpt-5.6-sol",
  input: "Explain machine learning basics",
  thread: {
    id: threadId,
    tags: ["education", "ml-basics", "beginner"],
  },
});

console.log(response.output_text);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import os
from openai import OpenAI
import uuid

client = OpenAI(
    api_key=os.environ["TOQAN_API_KEY"],
    base_url="https://router.toqan.ai/eu/v3/router",
)

thread_id = f"conversation-{uuid.uuid4()}"

response = client.responses.create(
    model="openai/gpt-5.6-sol",
    input="Explain machine learning basics",
    extra_body={
        "thread": {
            "id": thread_id,
            "tags": ["education", "ml-basics", "beginner"],
        }
    },
)

print(response.output_text)
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const threadId = `conversation-${crypto.randomUUID()}`;

const response = await client.chat.completions.create({
  model: "openai/gpt-5.6-sol",
  messages: [{ role: "user", content: "Explain machine learning basics" }],
  orq: {
    thread: {
      id: threadId,
      tags: ["education", "ml-basics", "beginner"],
    },
  },
});
```

```python Python (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import os
from openai import OpenAI
import uuid

client = OpenAI(
    api_key=os.environ["TOQAN_API_KEY"],
    base_url="https://router.toqan.ai/eu/v3/router",
)

thread_id = f"conversation-{uuid.uuid4()}"

response = client.chat.completions.create(
    model="openai/gpt-5.6-sol",
    messages=[{"role": "user", "content": "Explain machine learning basics"}],
    extra_body={
        "orq": {
            "thread": {
                "id": thread_id,
                "tags": ["education", "ml-basics", "beginner"],
            }
        }
    },
)
```

## Advanced Patterns

### Dynamic Thread Management

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

interface ThreadConfig {
  userId: string;
  sessionType: "support" | "sales" | "general";
  priority?: "low" | "medium" | "high";
}

function createThreadId(config: ThreadConfig): string {
  const timestamp = Date.now();
  return `${config.sessionType}-${config.userId}-${timestamp}`;
}

function generateTags(config: ThreadConfig): string[] {
  const baseTags = [config.sessionType, `user-${config.userId}`];

  if (config.priority) {
    baseTags.push(`priority-${config.priority}`);
  }

  return baseTags;
}

const threadConfig: ThreadConfig = {
  userId: "user123",
  sessionType: "support",
  priority: "high",
};

const response = await client.chat.completions.create({
  model: "openai/gpt-5.6-sol",
  messages: [{ role: "user", content: "Urgent: System not responding" }],
  orq: {
    thread: {
      id: createThreadId(threadConfig),
      tags: generateTags(threadConfig),
    },
  },
});
```

### Batch Thread Processing

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const conversations = [
  { userId: "user1", message: "Question about billing" },
  { userId: "user2", message: "Technical support needed" },
  { userId: "user3", message: "Feature request" },
];

const responses = await Promise.all(
  conversations.map(async (conv, index) => {
    return client.chat.completions.create({
      model: "openai/gpt-5.6-sol",
      messages: [{ role: "user", content: conv.message }],
      orq: {
        thread: {
          id: `batch-${Date.now()}-${index}`,
          tags: ["batch-processing", `user-${conv.userId}`],
        },
      },
    });
  }),
);
```

### Conversation Flow Tracking

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

// Track conversation progression
const conversationSteps = [
  "greeting",
  "problem-identification",
  "solution-proposal",
  "confirmation",
];

async function processConversationStep(step: string, threadId: string, message: string) {
  return await client.chat.completions.create({
    model: "openai/gpt-5.6-sol",
    messages: [{ role: "user", content: message }],
    orq: {
      thread: {
        id: threadId,
        tags: ["workflow", `step-${step}`, "customer-service"],
      },
    },
  });
}
```

## Troubleshooting

| Issue | Cause | Solution |
| - | - | - |
| Requests not grouping together | Different thread IDs used across requests | Use a consistent thread ID for all requests in the same session or workflow |
| Thread overlap | Non-unique thread IDs shared across sessions | Use UUID or timestamp-based IDs |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.